如何在 akka.net 中的事件处理程序中发送消息?
How to send a message in event handler in akka.net?
我有一个 actor,它有一个自定义计时器,可以在非实时间隔内触发事件。 (这就是我不能使用调度程序的原因)
在事件处理程序中,我想向自己或其他演员发送消息。我收到 NotSupportedException。
我有一个类似于 NodaTime FakeClock 的自定义时间源 class。
public class NodaTimeControllableClock
{
public void AddInterval(Duration interval);
public Instant Now { get; protected set; }
public event EventHandler<TimeChangedEventArgs<Duration>> TimeChanged;
}
它用于计时器class,每隔指定的时间触发一次事件。
public class NodaTimer
{
Duration Interval { get; set; }
void Start();
void Stop();
bool IsRunning { get; private set; }
event EventHandler<TimerTickedEventArgs> TimerTicked;
}
现在,我为我的一些演员创建了一个计时器实例并将其存储在其中。
protected override void PreStart()
{
base.PreStart();
timer.Interval = Duration.FromSeconds(1);
timer.TimerTicked += Timer_TimerTicked;
timer.Start();
}
private void Timer_TimerTicked(object sender, TimerTickedEventArgs e)
{
Self.Tell(new SomeMessage());
//Here I want to send the message to the parent or
//if it's impossible to do so I could queue some message
//to the Self messagebox.
}
发送事件消息的模式是什么?有没有?
问题的根源可能是 Self
在 Timer_TimerTicked
内部进行的成员调用。这样做的原因是 Self
就像 Context
是计算的 属性,它仅在当前执行的 actor 线程中可用。如果你从外部调用它(另一个线程,比如定时器回调),它可能没有被初始化。
弱解决方案是将对 Self
的引用存储在其他字段中,然后使用该字段发送消息。
在您的情况下,更好的解决方案是使用内置的 Akka.NET 调度程序,它可以在指定的时间间隔内执行操作或进行调用:
class MyActor : ReceiveActor
{
private readonly ICancelable cancelTimer;
public MyActor()
{
var interval = TimeSpan.FromSeconds(1);
cancelTimer = Context.System.Scheduler
.ScheduleTellRepeatedlyCancelable(interval, interval, Self, new SomeMessage(), ActorRefs.NoSender);
}
protected override void PostStop()
{
cancelTimer.Cancel();
base.PostStop();
}
}
我有一个 actor,它有一个自定义计时器,可以在非实时间隔内触发事件。 (这就是我不能使用调度程序的原因) 在事件处理程序中,我想向自己或其他演员发送消息。我收到 NotSupportedException。
我有一个类似于 NodaTime FakeClock 的自定义时间源 class。
public class NodaTimeControllableClock
{
public void AddInterval(Duration interval);
public Instant Now { get; protected set; }
public event EventHandler<TimeChangedEventArgs<Duration>> TimeChanged;
}
它用于计时器class,每隔指定的时间触发一次事件。
public class NodaTimer
{
Duration Interval { get; set; }
void Start();
void Stop();
bool IsRunning { get; private set; }
event EventHandler<TimerTickedEventArgs> TimerTicked;
}
现在,我为我的一些演员创建了一个计时器实例并将其存储在其中。
protected override void PreStart()
{
base.PreStart();
timer.Interval = Duration.FromSeconds(1);
timer.TimerTicked += Timer_TimerTicked;
timer.Start();
}
private void Timer_TimerTicked(object sender, TimerTickedEventArgs e)
{
Self.Tell(new SomeMessage());
//Here I want to send the message to the parent or
//if it's impossible to do so I could queue some message
//to the Self messagebox.
}
发送事件消息的模式是什么?有没有?
问题的根源可能是 Self
在 Timer_TimerTicked
内部进行的成员调用。这样做的原因是 Self
就像 Context
是计算的 属性,它仅在当前执行的 actor 线程中可用。如果你从外部调用它(另一个线程,比如定时器回调),它可能没有被初始化。
弱解决方案是将对 Self
的引用存储在其他字段中,然后使用该字段发送消息。
在您的情况下,更好的解决方案是使用内置的 Akka.NET 调度程序,它可以在指定的时间间隔内执行操作或进行调用:
class MyActor : ReceiveActor
{
private readonly ICancelable cancelTimer;
public MyActor()
{
var interval = TimeSpan.FromSeconds(1);
cancelTimer = Context.System.Scheduler
.ScheduleTellRepeatedlyCancelable(interval, interval, Self, new SomeMessage(), ActorRefs.NoSender);
}
protected override void PostStop()
{
cancelTimer.Cancel();
base.PostStop();
}
}