gpt4 book ai didi

c# - 如何创建自定义 SynchronizationContext 以便所有延续都可以由我自己的单线程事件循环处理?

转载 作者:太空狗 更新时间:2023-10-29 18:24:28 27 4
gpt4 key购买 nike

假设您正在编写自定义单线程 GUI 库(或任何带有事件循环的库)。根据我的理解,如果我使用 async/await,或者只是常规的 TPL 延续,它们将全部安排在 TaskScheduler.Current(或 SynchronizationContext.Current)。

问题是延续可能想要访问库的单线程部分,这意味着它必须在同一个事件循环中执行。例如,给定一个简单的游戏循环,事件可能会像这样处理:

// All continuation calls should be put onto this queue
Queue<Event> events;

// The main thread calls the `Update` method continuously on each "frame"
void Update() {
// All accumulated events are processed in order and the queue is cleared
foreach (var event : events) Process(event);

events.Clear();
}

现在假设我的假设是正确的并且 TPL 使用 SynchronizationContext.Current,应用程序中的任何代码都应该能够执行如下操作:

async void Foo() {
someLabel.Text = "Processing";

await BackgroundTask();

// This has to execute on the main thread
someLabel.Text = "Done";
}

这让我想到了这个问题。 我如何实现自定义 SynchronizationContext 以允许我在自己的线程上处理延续?这是正确的方法吗?

最佳答案

实现自定义 SynchronizationContext 并不是世界上最简单的事情。我有一个开源单线程实现 here您可以将其用作起点(或者可能只是用来代替您的主循环)。

默认情况下,AsyncContext.Run 采用单个委托(delegate)来执行并在完全完成时返回(因为 AsyncContext 使用自定义 SynchronizationContext ,它能够等待 async void 方法以及常规的异步/同步代码)。

AsyncContext.Run(async () => await DoSomethingAsync());

如果您想要更大的灵 active ,您可以使用 AsyncContext 高级成员(它们不会出现在 IntelliSense 中,但它们在那里)来保持上下文事件直到某些外部信号(如“退出帧” "):

using (var context = new AsyncContext())
{
// Ensure the context doesn't exit until we say so.
context.SynchronizationContext.OperationStarted();

// TODO: set up the "exit frame" signal to call `context.SynchronizationContext.OperationCompleted()`
// (note that from within the context, you can alternatively call `SynchronizationContext.Current.OperationCompleted()`

// Optional: queue any work you want using `context.Factory`.

// Run the context; this only returns after all work queued to this context has completed and the "exit frame" signal is triggered.
context.Execute();
}

AsyncContextRunExecute 在运行时替换当前的 SynchronizationContext,但它们保存原始上下文并在返回之前将其设置为当前上下文。这允许它们以嵌套方式(例如,“框架”)很好地工作。

(我假设“框架”是指一种类似于 WPF 的调度程序框架)。

关于c# - 如何创建自定义 SynchronizationContext 以便所有延续都可以由我自己的单线程事件循环处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39271492/

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