gpt4 book ai didi

c# - 是否可以在控制台应用程序的 "main"线程上运行异步回调?

转载 作者:行者123 更新时间:2023-11-30 20:37:52 25 4
gpt4 key购买 nike

在 GUI 应用程序中,有很多方法可以运行异步代码并在“主”线程上运行结果:

  • 使用async/await
  • 使用BackgroundWorker
  • someControl.Invoke()
  • .ContinueWith(..., TaskScheduler.FromCurrentSynchronizationContext())

等等

但是,这些选项在控制台应用程序中都不起作用,因为没有同步上下文或 GUI 运行循环。

我正在修改一个控制台项目,它有自己的手动运行循环。像这样:

while (!cancelled)
{
if(api.HasMessage())
{
api.HandleMessage();
}
Thread.Sleep(1);
}

我希望能够在此项目中发出异步网络请求,同时仍在主运行循环线程上处理结果以避免典型的多线程问题。当然,我可以使用队列手动执行此操作,但如果能够使用 async/await 或其他可以更好地处理此问题的范例之一,那就太好了。

有没有我可以从运行循环中调用的方法来实现这一点?我在想像 Thread.ResolveCurrentAwaitingTasks() 之类的东西。

最佳答案

这不像调用一个方法那么简单,因为 async continuations 被安排到 SynchronizationContextTaskScheduler,而不是 线程。因此,您必须编写其中一个 - 这不是一个非常有趣的前景。

您可以使用SynchronizationContext that I wrote称为 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()

关于c# - 是否可以在控制台应用程序的 "main"线程上运行异步回调?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35676488/

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