简体   繁体   English

自定义TaskScheduler,SynchronizationContext?

[英]Custom TaskScheduler, SynchronizationContext?

async await support within actors async等待演员内部的支持

I'm porting the actor lib Akka to .NET ( https://github.com/rogeralsing/Pigeon ) I want to add async/await support inside my actors. 我将演员lib Akka移植到.NET( https://github.com/rogeralsing/Pigeon )我想我的演员中添加async / await支持。

This gives me some problems right now since if I use the default scheduler, the await continuation will run w/o respect to the actors concurrency boundarys. 这给了我一些问题,因为如果我使用默认调度程序,await continuation将运行与actor并发boundarys相关。 Meaning, the continuation may run when the actor is processing a message since that would lead to two threads accessing the actors internal state at the same time. 这意味着,当actor处理消息时,可以继续运行,因为这将导致两个线程同时访问actor内部状态。

If I could somehow schedule the the tasks to the actors own mailbox, and complete the task in the mailbox run, this would solve the problem. 如果我能以某种方式将任务安排到演员自己的邮箱,并在邮箱运行中完成任务,这将解决问题。

 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);
      }
 }

I do have a thread static context for the actor, so when the actor is executing, this context is set. 我确实有一个actor的线程静态上下文,所以当actor执行时,这个上下文被设置。 So I could easily lookup the active actors mailbox from a task scheduler. 所以我可以轻松地从任务调度程序中查找活动的actor邮箱。 Something along the lines of: 有点像:

public class ActorTaskScheduler : TaskScheduler
{
    protected override void QueueTask(Task task)
    {            
        var self = ActorCell.Current.Self;
        self.Tell(new ActorTask(task), ActorRef.NoSender);
    }

And the ActorTask message could be handled by the system message handler of the actor. 并且ActorTask消息可以由actor的系统消息处理程序处理。 So far so good. 到现在为止还挺好。

I just don't know what to do next. 我只是不知道接下来该做什么。 Can I just over write the current TaskScheduler? 我可以过度编写当前的TaskScheduler吗? Is that thread static? 该线程是静态的吗? I just want to apply this scheduler when an actor is running, it may not affect code running outside the actors. 我只是想在actor运行时应用这个调度程序,它可能不会影响在actor之外运行的代码。

Is this possible at all to apply custom task schedulers for specific actions only? 这是否可以仅针对特定操作应用自定义任务调度程序?

Can I just over write the current TaskScheduler? 我可以过度编写当前的TaskScheduler吗?

The proper way to "set" the current scheduler is to queue a delegate to the scheduler you want. “设置”当前调度程序的正确方法是将委托排队到所需的调度程序。 When the delegate executes, it will have that scheduler as "current". 当委托执行时,它将该调度程序作为“当前”。

I do have a thread static context for the actor, so when the actor is executing, this context is set. 我确实有一个actor的线程静态上下文,所以当actor执行时,这个上下文被设置。

Is it possible to do this another way? 是否有可能以另一种方式做到这一点? Because then you have an easier solution available. 因为那时你有一个更简单的解决方案。

I'm thinking you could just run each actor inside a ConcurrentExclusiveSchedulerPair.ExclusiveScheduler . 我想你可以在ConcurrentExclusiveSchedulerPair.ExclusiveScheduler运行每个actor。 This would mean any actor code runs on a thread pool thread; 这意味着任何actor代码都在线程池线程上运行; it could be any thread pool thread, but the ExclusiveScheduler will ensure only one part of actor code would run at a time. 它可以是任何线程池线程,但ExclusiveScheduler将确保一次只运行一部分actor代码。

This "lifts" the actor abstraction from threads to tasks, which is an approach I would recommend if you could do it. 这会将演员抽象从线程“提升”到任务,这是我建议的方法,如果你能做到的话。 It relieves pressure on memory and the thread pool when you have async actors. 当你有异步演员时,它减轻了内存和线程池的压力。 Of course, things like thread statics can't be used then, so you have to use something like logical call context or a Current value that is set by a custom SynchronizationContext or TaskScheduler . 当然,当时不能使用线程静态等内容,因此必须使用逻辑调用上下文或由自定义SynchronizationContextTaskScheduler设置的Current值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 当前的SynchronizationContext可能不会用作TaskScheduler - The current SynchronizationContext may not be used as a TaskScheduler 默认SynchronizationContext与默认TaskScheduler - Default SynchronizationContext vs Default TaskScheduler 获取TaskScheduler / SynchronizationContext以在特定线程上执行 - Getting a TaskScheduler/SynchronizationContext to execute on a specific thread SynchronizationContext 和 TaskScheduler 之间的概念区别是什么 - What is the conceptual difference between SynchronizationContext and TaskScheduler 当前的SynchronizationContext可能不用作TaskScheduler。 来自CEFsharp EvaluateScriptAsync - The current SynchronizationContext may not be used as a TaskScheduler. from CEFsharp EvaluateScriptAsync 自定义TaskScheduler通过DateTime启动任务 - Custom TaskScheduler to start task by DateTime 处理任务异常 - 自定义TaskScheduler - Handling Task Exceptions - custom TaskScheduler 启动线程返回System.InvalidOperationException:当前的SynchronizationContext不能用作TaskScheduler - Start thread returns System.InvalidOperationException: The current SynchronizationContext may not be used as a TaskScheduler 如何从自定义TaskScheduler回退到Default TaskScheduler - How do I fallback to the Default TaskScheduler from a custom TaskScheduler 自定义 TaskFactory 不使用自定义 SynchronizationContext - Custom TaskFactory does not use custom SynchronizationContext
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM