PID對象是代表Actor對象的進程,是能過Actor.Spawn(props)獲取的;它有什麼成員呢?既然代理Actor,首先有一個ID,標識自己是誰,Actor在Spawn時可以命名這個ID,否則會自動生成。還有三種向郵箱發消息的方法,Tell(),Request(),RequestAsync(... ...
PID對象是代表Actor對象的進程,是能過Actor.Spawn(props)獲取的;它有什麼成員呢?既然代理Actor,首先有一個ID,標識自己是誰,Actor在Spawn時可以命名這個ID,否則會自動生成。還有三種向郵箱發消息的方法,Tell(),Request(),RequestAsync(),還有一個發送系統消息(Started,Stoping,Stoped等)方法SendSystemMessage(),還有一個停止的方法Stop()。
1 using Proto; 2 using System; 3 using System.Threading; 4 using System.Threading.Tasks; 5 6 namespace P004_PID 7 { 8 class Program 9 { 10 static void Main(string[] args) 11 { 12 var props = Actor.FromProducer(() => new MyActor()); 13 var pid = Actor.Spawn(props); 14 while (true) 15 { 16 Console.WriteLine("**************************************"); 17 Console.WriteLine("1、單向請求Tell 2、單向請求Request 3、雙向請求RequestAsync"); 18 switch (Console.ReadLine()) 19 { 20 case "1": 21 Console.WriteLine("單向請求開始"); 22 pid.Tell(new Request { Name = "單向請求 Tell", RequestType = "one-way", Time = DateTime.Now }); 23 break; 24 case "2": 25 Console.WriteLine("單向請求開始"); 26 //無法接回應簽,與官網說法不一 27 pid.Request(new Request { Name = "單向請求 Request", RequestType = "two-way-1", Time = DateTime.Now }, pid); 28 29 break; 30 case "3": 31 Console.WriteLine("雙向請求開始"); 32 var response = pid.RequestAsync<Response>(new Request { Name = "雙向請求 RequestAsync", RequestType = "two-way-2", Time = DateTime.Now }).Result; 33 Console.WriteLine(response.Time + ":" + response.Name); 34 break; 35 } 36 Thread.Sleep(2000); 37 } 38 } 39 } 40 41 public class MyActor : IActor 42 { 43 public Task ReceiveAsync(IContext context) 44 { 45 46 if (context.Message is Request request) 47 { 48 switch (request.RequestType) 49 { 50 case "one-way"://context.Sender為null 51 Console.WriteLine("接收到:" + request.RequestType + "," + request.Time + ":" + request.Name); 52 break; 53 case "two-way-1"://context.Sender= context.Self為自己 54 Console.WriteLine("接收到:" + request.RequestType + "," + request.Time + ":" + request.Name); 55 context.Respond(new Response() { Time = DateTime.Now, Name = "服務端應答 two-way-1" }); 56 break; 57 case "two-way-2"://context.Sender!= context.Self為新實例 58 Console.WriteLine("接收到:" + request.RequestType + "," + request.Time + ":" + request.Name); 59 context.Respond(new Response() { Time = DateTime.Now, Name = "服務端應答 two-way-2" }); 60 break; 61 } 62 } 63 return Actor.Done; 64 } 65 } 66 67 public class Request 68 { 69 public string Name 70 { get; set; } 71 public string RequestType 72 { get; set; } 73 public DateTime Time 74 { get; set; } 75 } 76 77 public class Response 78 { 79 public string Name 80 { get; set; } 81 public DateTime Time 82 { get; set; } 83 } 84 }
Actor中的Receive接到消息後,Context是中有兩個PID對象,一個Self,一個Sender,Tell方法到達後,Sender對象為空;Request到達後,Sender=Self;而RequestAsync則Sender,Self都有對象,但不相同,這是一個區別。再有就是Tell和Request都是單向調用(我實測與官方文檔說明有出入),RequestAsync是可以有返回值的,詳見代碼,如下是運行結果: