C# 自定义任务计划程序,同步上下文?
异步等待参与者的支持 我正在将actor lib Akka移植到.NET() 我想在我的参与者中添加async/await支持 这就给了我一些问题,因为如果我使用默认的调度程序,wait continuation将针对actors并发边界运行w/o。 也就是说,在参与者处理消息时可能会运行continuation,因为这将导致两个线程同时访问参与者的内部状态 如果我能以某种方式将任务安排到参与者自己的邮箱,并在邮箱运行中完成任务,这将解决问题C# 自定义任务计划程序,同步上下文?,c#,multithreading,concurrency,task-parallel-library,async-await,C#,Multithreading,Concurrency,Task Parallel Library,Async Await,异步等待参与者的支持 我正在将actor lib Akka移植到.NET() 我想在我的参与者中添加async/await支持 这就给了我一些问题,因为如果我使用默认的调度程序,wait continuation将针对actors并发边界运行w/o。 也就是说,在参与者处理消息时可能会运行continuation,因为这将导致两个线程同时访问参与者的内部状态 如果我能以某种方式将任务安排到参与者自己的邮箱,并在邮箱运行中完成任务,这将解决问题 public class SomeActor :
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);
}
}
我确实为actor提供了一个线程静态上下文,因此当actor执行时,就设置了这个上下文。
因此,我可以轻松地从任务调度器中查找活动参与者邮箱。
大致如下:
public class ActorTaskScheduler : TaskScheduler
{
protected override void QueueTask(Task task)
{
var self = ActorCell.Current.Self;
self.Tell(new ActorTask(task), ActorRef.NoSender);
}
ActorTask消息可以由参与者的系统消息处理程序处理。
到目前为止还不错
我只是不知道下一步该怎么办。
我可以重写当前的TaskScheduler吗?
那根线是静态的吗?
我只想在参与者运行时应用此调度程序,它可能不会影响参与者外部运行的代码
这是否可能仅对特定操作应用自定义任务调度程序
我可以重写当前的TaskScheduler吗
“设置”当前计划程序的正确方法是将委托排队给所需的计划程序。当委托执行时,它将该调度程序设置为“当前”
我确实为actor提供了一个线程静态上下文,因此当actor执行时,就设置了这个上下文
有没有可能用另一种方法?因为这样你就有了一个更简单的解决方案
我想你可以在一个ConcurrentExclusiveSchedulerPair.ExclusiveScheduler
中运行每个参与者。这意味着任何参与者代码都在线程池线程上运行;它可以是任何线程池线程,但是ExclusiveScheduler
将确保一次只运行参与者代码的一部分
这将参与者抽象从线程“提升”到任务,如果您能够做到这一点,我建议您使用这种方法。当您有异步参与者时,它减轻了内存和线程池的压力。当然,像线程静态这样的东西是不能使用的,所以你必须使用像逻辑调用上下文或由自定义SynchronizationContext
或TaskScheduler
线程静态设置的Current
值之类的东西。你是说共享static
数据还是实际ThreadLocal
数据?