Jak*_*old 8 c# multithreading asynchronous async-await
假设您正在编写自定义单线程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();
}
Run Code Online (Sandbox Code Playgroud)
现在假设我的假设是正确的并且TPL使用了SynchronizationContext.Current,应用程序中的任何代码都应该能够执行以下操作:
async void Foo() {
someLabel.Text = "Processing";
await BackgroundTask();
// This has to execute on the main thread
someLabel.Text = "Done";
}
Run Code Online (Sandbox Code Playgroud)
这让我想到了这个问题.如何实现SynchronizationContext允许我在自己的线程上处理延续的自定义?这甚至是正确的方法吗?
Ste*_*ary 11
实施定制SynchronizationContext并不是世界上最容易的事情.我在这里有一个开源的单线程实现,您可以将其用作起点(或者可以仅使用代替主循环).
默认情况下,AsyncContext.Run执行单个委托并在完全完成时返回(因为AsyncContext使用自定义SynchronizationContext,它可以等待async void方法以及常规异步/同步代码).
AsyncContext.Run(async () => await DoSomethingAsync());
Run Code Online (Sandbox Code Playgroud)
如果你想要更多的灵活性,你可以使用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();
}
Run Code Online (Sandbox Code Playgroud)
AsyncContext的Run,并Execute取代现有的SynchronizationContext,而他们正在运行,但它们保存原始上下文并设置返回为当前之前.这允许它们以嵌套方式(例如,"帧")很好地工作.
(我假设"框架"你的意思是一种类似WPF的调度程序框架).
| 归档时间: |
|
| 查看次数: |
2680 次 |
| 最近记录: |