网上关于Actor的内容有很多,这里提供一种简单的实现。直接上码:
1 public abstract class Actor<T>
2 {
3 public static readonly int StateWaiting = 0;
4 public static readonly int StateExecuting = 1;
5 public static readonly int StateExit = 2;
6
7 private readonly Queue<T> _messages;
8 private volatile int _status;
9
10 public bool IsBusy => _status == StateExecuting;
11
12 protected Actor()
13 {
14 _messages = new Queue<T>();
15 }
16
17 public void Receive(T message)
18 {
19 if (IsValid(message))
20 {
21 lock (_messages)
22 {
23 _messages.Enqueue(message);
24 }
25
26 StartHandleMessage();
27 }
28 }
29
30 protected abstract bool IsValid(T message);
31
32 private void StartHandleMessage()
33 {
34 if (Interlocked.CompareExchange(ref _status, StateExecuting, StateWaiting) == StateWaiting)
35 {
36 var msg = _messages.Dequeue();
37 ThreadPool.QueueUserWorkItem(DoHandleMessage, msg);
38 }
39 }
40
41 private void DoHandleMessage(object message)
42 {
43 if (_status != StateExit)
44 {
45 HandleMessageImpl((T)message);
46
47 if (_messages.Count > 0)
48 {
49 var msg = _messages.Dequeue();
50 DoHandleMessage(msg);
51 }
52 else
53 {
54 _status = StateWaiting;
55 }
56 }
57 }
58
59 protected abstract void HandleMessageImpl(T message);
60
61 public void Exit()
62 {
63 _status = StateExit;
64 }
65 }
66 }
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/279958.html