异步等待参与者的支持
我正在将参与者库Akka移植到.NET (https://github.com/rogeralsing/Pigeon),我想在参与者中添加异步/等待支持。
这给我带来了一些问题,因为如果我使用默认的调度程序,等待延续将针对参与者并发边界运行w/o。也就是说,当参与者正在处理一条消息时,该延续可能会运行,因为这将导致两个线程同时访问参与者内部状态。
如果我可以以某种方式将任务安排到参与者自己的邮箱,并在邮箱运行中完成任务,这将解决问题。
public class SomeActor : UntypedActor
{
protected override OnReceive(object message)
{
if (message is SomeMessage)
{
DoAsyncStuff();
}
}
private async void DoAsyncStuff()
{
var res = await something..
//this code will not respect the actor concurrency boundary
//since it can run at the same time as OnReceive
Console.WriteLine(res);
}
}我确实为参与者提供了一个线程静态上下文,所以当参与者执行时,这个上下文就会被设置。因此,我可以轻松地从任务调度程序中查找活动参与者邮箱。与…有关的东西:
public class ActorTaskScheduler : TaskScheduler
{
protected override void QueueTask(Task task)
{
var self = ActorCell.Current.Self;
self.Tell(new ActorTask(task), ActorRef.NoSender);
}ActorTask消息可以由参与者的系统消息处理程序处理。到目前一切尚好。
我只是不知道下一步该怎么办。我可以重写当前的TaskScheduler吗?那个线是静态的吗?我只想应用这个调度程序时,当一个演员正在运行,它可能不会影响代码运行以外的参与者。
这是否可能仅适用于特定操作的自定义任务调度程序?
发布于 2014-02-23 13:13:12
我可以重写当前的TaskScheduler吗?
“设置”当前调度程序的正确方法是将委托排队到所需的调度程序。当委托执行时,它将将该调度程序作为“当前”。
我确实为参与者提供了一个线程静态上下文,所以当参与者执行时,这个上下文就会被设置。
有可能换一种方法吗?因为这样你就有了一个更简单的解决方案。
我想你可以把每个演员都放进ConcurrentExclusiveSchedulerPair.ExclusiveScheduler里。这意味着任何参与者代码都运行在线程池线程上;它可能是任何线程池线程,但是ExclusiveScheduler将确保一次只运行一部分参与者代码。
这种“将参与者抽象从线程提升到任务”的方法是我推荐的一种方法,如果您可以这样做的话。当您有异步参与者时,它可以减轻内存和线程池的压力。当然,像线程静力学这样的东西不能使用,所以您必须使用诸如逻辑调用上下文或由自定义SynchronizationContext或TaskScheduler设置的一个TaskScheduler值。
https://stackoverflow.com/questions/21965772
复制相似问题