Blu*_*eft 4 c# multithreading console-application task-parallel-library async-await
在 GUI 应用程序中,有很多方法可以运行异步代码并在“主”线程上运行结果:
async/awaitBackgroundWorkersomeControl.Invoke().ContinueWith(..., TaskScheduler.FromCurrentSynchronizationContext())等等等等
但是,这些选项都不适用于控制台应用程序,因为没有同步上下文或 GUI 运行循环。
我正在修改一个控制台项目,它有自己的手动运行循环。像这样的东西:
while (!cancelled)
{
if(api.HasMessage())
{
api.HandleMessage();
}
Thread.Sleep(1);
}
Run Code Online (Sandbox Code Playgroud)
我希望能够在这个项目中进行异步 web 请求,同时仍然在主运行循环线程上处理结果以避免典型的多线程问题。当然,我可以使用队列手动执行此操作,但是能够使用async/await或其他可以更好地处理此问题的范例之一会很好。
有没有我可以从运行循环调用的方法来实现这一点?我在想象这样的事情,比如说,Thread.ResolveCurrentAwaitingTasks()。
这并不像仅仅调用一个方法那么容易,因为async延续被调度到一个SynchronizationContextor TaskScheduler,而不是一个thread。因此,您必须编写其中之一 - 不是一个非常有趣的前景。
你可以使用SynchronizationContext 我写的一个叫做AsyncContext; 正常使用如下:
AsyncContext.Run(() =>
{
while (!cancelled)
{
if(api.hasMessage())
{
api.handleMessage();
}
Thread.Sleep(1);
}
});
Run Code Online (Sandbox Code Playgroud)
这适用于async代码:
AsyncContext.Run(async () =>
{
while (!cancelled)
{
if(api.hasMessage())
{
await api.handleMessageAsync();
}
Thread.Sleep(1);
}
});
Run Code Online (Sandbox Code Playgroud)
虽然我必须说这Thread.Sleep有点hackish。我会考虑使用事件或其他类型的消息到达通知,例如await api.GetNextMessageAsync().