Fork me on GitHub

《通过C#学Proto.Actor模型》之Behaviors

Behaviors就是Actor接收到消息后可以改变处理的方法,相同的Actor,每次调用,转到不同的Actor内方法执行,非常适合按流程进行的场景。Behaviors就通过在Actor内部实例化一个Behavior对象,然后通过这个对象的Become来切换执行的方法的。

 码友看码:

 1 using Proto;
 2 using System;
 3 using System.Threading.Tasks;
 4 
 5 namespace P007_Behaviors
 6 {
 7     class Program
 8     {
 9         static void Main(string[] args)
10         {
11             var props = Actor.FromProducer(() => new LightBulb());
12             var pid = Actor.Spawn(props);
13             while (true)
14             {
15                 Console.WriteLine("----------------------------");
16                 Console.WriteLine("按开关");
17                 Console.ReadLine();
18                 var message = pid.RequestAsync<string>(new PressSwitch()).Result;
19                 Console.WriteLine(message);
20 
21                 message = pid.RequestAsync<string>(new Touch()).Result;
22                 Console.WriteLine(message);
23             }
24         }
25     }
26 
27     public class LightBulb : IActor
28     {
29         private readonly Behavior _behavior;
30 
31         public LightBulb()
32         {
33             _behavior = new Behavior();
34             //把Off方法放入栈
35             _behavior.BecomeStacked(Off);
36         }
37         public Task ReceiveAsync(IContext context)
38         {
39             //切换到behavior指定的方法,来充当ReceiveAsync
40             return _behavior.ReceiveAsync(context);
41         }
42         /// <summary>
43         ///44         /// </summary>
45         /// <param name="context"></param>
46         /// <returns></returns>
47         private Task Off(IContext context)
48         {
49             switch (context.Message)
50             {
51                 case PressSwitch _:
52                     context.Respond("打开");
53                     _behavior.Become(On);
54                     break;
55                 case Touch _:
56                     context.Respond("凉的");
57                     break;
58             }
59             return Actor.Done;
60         }
61         /// <summary>
62         ///63         /// </summary>
64         /// <param name="context"></param>
65         /// <returns></returns>
66         private Task On(IContext context)
67         {
68             switch (context.Message)
69             {
70                 case PressSwitch _:
71                     context.Respond("关闭");
72                     _behavior.Become(Off);
73                     break;
74                 case Touch _:
75                     context.Respond("烫手");
76                     break;
77             }
78             return Actor.Done;
79         }
80     }
81     class PressSwitch
82     { }
83     class Touch
84     { }
85 
86 }

几个要点,在Actor构造中把Off放入方法栈,在Receive中调用Behavior的Receive,同时可以按自己业务逻辑切换方法,这样在一定程度上增加了Actor的灵活性,让一个Actor可以按设定流程实现不同行为。

Behavior提供了三个切换方法相关的方法:

  • Become只需将传递的Receive方法设置为当前方法,替换默认方法。
  • BecomeStacked将传递的Receive方法推送到方法堆栈,但保留以前的方法。
  • UnbecomeStacked 恢复到以前使用的方法。

看结果:

posted @ 2018-09-01 08:43  桂素伟  阅读(1468)  评论(0编辑  收藏  举报