在GUI应用程序中,有很多方法可以运行异步代码并在“主”线程上运行结果:
async
/ await
BackgroundWorker
someControl.Invoke()
.ContinueWith(..., TaskScheduler.FromCurrentSynchronizationContext())
等。等
但是,这些选项都不适用于控制台应用程序,因为没有同步上下文或GUI运行循环。
我正在修改一个具有自己的手动运行循环的控制台项目。像这样:
while (!cancelled)
{
if(api.HasMessage())
{
api.HandleMessage();
}
Thread.Sleep(1);
}
我希望能够在这个项目中创建异步Web请求,同时仍然在主运行循环线程上处理结果,以避免典型的多线程问题。当然我可以使用队列手动执行此操作,但是能够使用async
/ await
或其他一种处理这种更好的范例会很好。
我是否可以通过运行循环调用方法来实现此目的?我想象的是,Thread.ResolveCurrentAwaitingTasks()
。
答案 0 :(得分:4)
它不像调用方法那么容易,因为async
延续被安排到SynchronizationContext
或TaskScheduler
,而不是线程 。所以,你必须写下其中一个 - 不是一个非常有趣的前景。
您可以使用名为that I wrote的SynchronizationContext
AsyncContext
;正常用法如下:
AsyncContext.Run(() =>
{
while (!cancelled)
{
if(api.hasMessage())
{
api.handleMessage();
}
Thread.Sleep(1);
}
});
这适用于async
代码:
AsyncContext.Run(async () =>
{
while (!cancelled)
{
if(api.hasMessage())
{
await api.handleMessageAsync();
}
Thread.Sleep(1);
}
});
虽然我必须说Thread.Sleep
有点hackish。我考虑使用事件或其他类型的邮件到达通知,例如await api.GetNextMessageAsync()
。