gpt4 book ai didi

c# - 自定义 TaskScheduler、SynchronizationContext?

转载 作者:行者123 更新时间:2023-11-30 14:10:53 29 4
gpt4 key购买 nike

actors 中的异步等待支持

我正在将 actor 库 Akka 移植到 .NET ( https://github.com/rogeralsing/Pigeon )我想在我的 Actor 内部添加async/await支持。

这现在给我带来了一些问题,因为如果我使用默认调度程序,等待延续将在不考虑参与者并发边界的情况下运行。这意味着,延续可能会在 actor 处理消息时运行,因为这会导致两个线程同时访问 actor 的内部状态。

如果我能以某种方式将任务安排到 Actor 自己的邮箱,并在邮箱运行中完成任务,这将解决问题。

 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 消息可以由 actor 的系统消息处理程序处理。到目前为止一切顺利。

我只是不知道下一步该做什么。我可以直接覆盖当前的 TaskScheduler 吗?该线程是静态的吗?我只想在 actor 运行时应用此调度程序,它可能不会影响在 actor 外部运行的代码。

是否可以仅针对特定操作应用自定义任务调度程序?

最佳答案

Can I just over write the current TaskScheduler?

“设置”当前调度程序的正确方法是将委托(delegate)排队到您想要的调度程序。当委托(delegate)执行时,它将把该调度程序作为“当前”。

I do have a thread static context for the actor, so when the actor is executing, this context is set.

是否可以用其他方式做到这一点?因为这样您就有了更简单的解决方案。

我认为您可以在 ConcurrentExclusiveSchedulerPair.ExclusiveScheduler 中运行每个 actor。这意味着任何参与者代码都在线程池线程上运行;它可以是任何线程池线程,但ExclusiveScheduler 将确保一次只有一部分参与者代码运行。

这将 actor 抽象从线程“提升”到任务,如果可以的话,我会推荐这种方法。当你有异步 actor 时,它可以减轻内存和线程池的压力。当然,那时不能使用诸如线程静态之类的东西,因此您必须使用诸如逻辑调用上下文之类的东西或由自定义 SynchronizationContext 设置的 Current 值或任务调度器

关于c# - 自定义 TaskScheduler、SynchronizationContext?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21965772/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com