网上关于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 }