C# 为什么在控制台应用程序中使用async/await时需要AsyncContext?

C# 为什么在控制台应用程序中使用async/await时需要AsyncContext?,c#,.net,asynchronous,async-await,console-application,C#,.net,Asynchronous,Async Await,Console Application,我正在控制台应用程序中调用一个异步方法。我不希望应用程序在启动后不久即在等待的任务完成之前退出。看来我能做到: internal static void Main(string[] args) { try { Task.WaitAll(DoThisAsync()); } catch (Exception ex) { Console.Error.WriteLine(ex); throw; } } in

我正在控制台应用程序中调用一个异步方法。我不希望应用程序在启动后不久即在等待的任务完成之前退出。看来我能做到:

internal static void Main(string[] args)
{
    try
    {
        Task.WaitAll(DoThisAsync());
    }
    catch (Exception ex)
    {
        Console.Error.WriteLine(ex);
        throw;
    }
}

internal static async Task DoThisAsync()
{
    //...
}
但据我所知,我似乎无法做到这一点,而是应该为异步创建某种上下文,以便异步完成后返回(例如)


但是上面的代码可以工作,它在
Task.WaitAll(dothisaync())之后返回主线程,那么为什么我需要使用自定义上下文呢?

这不是必需的;这只是我的喜好

您可以在
Main
中同步阻止任务(使用
Wait
/
Result
/
WaitAll
)。语义略有不同;特别是,如果异步代码失败,则
Wait
/
Result
/
WaitAll
将异常包装在
aggregateeexception
中,而
AsyncContext
不会

另外,
AsyncContext
专门处理主线程;它不会将continuations发送到线程池,而是将它们发送回主线程(默认情况下,您可以始终使用
configurewait(false)
来避免这种情况)。如果我正在编写一个“概念验证”控制台应用程序,我会发现这很有用,因为
AsyncContext
的行为与UI上下文非常相似


但归根结底,这只是一个偏好问题。

使用threadpool时可能会发生这种情况。线程池线程是后台线程,只有主线程是前台线程。UI应用程序将有一个主循环,不允许它们在某些事情发生之前退出,而控制台应用程序通常没有这个循环。因此,如果您不阻止主线程等待某些东西,那么您的应用程序将简单地退出,您在线程池上所做的工作也将消失。不过我不确定。正如@StephenCleary提到的,这只是一种偏好。如何阻止线程并不重要,你只需要知道,如果你不以某种方式管理该线程,你的应用程序将退出(即使你的其他线程没有完成)@Brandon好吧,这很重要。它们的功能不同,但当然可以使用这两种方法编写工作程序。我必须记住,使用AsyncContext的一个关键目的是模拟UI。如果您所做的只是防止聚合异常,为什么需要这么多代码?我看到了TaskScheduler、TaskQueue(BlockingQueue)、TaskFactory和AsyncContextSynchronizationContext。我看到一个AsyncContextThread,它说它执行AsyncContext的操作。我想我的观点是,这里似乎发生了很多事情,但我还没有找到一篇关于实际发生的事情的好文章。我没有时间去试着解释发生了什么。@crush:没有,
AsyncContext
基本上是一个消息循环,只有在所有异步操作完成后才会退出。我不建议在一般情况下使用它作为
结果
替换。对于控制台的
Main
方法,使用
Result
AsyncContext
都可以;在一般情况下,您应该使用
wait
而不是
Result
,而且绝对不能使用
AsyncContext
@stephenleary感谢您的回复。我刚发现(读)你的书,它真的把事情弄清楚了。这很好地总结了我的情况:“对于那些“埋头”异步编程的程序员来说,这是一个特别常见的问题,他们只转换应用程序的一小部分,并将其包装到同步API中,以便将应用程序的其余部分与更改隔离开来。”似乎存在
AsyncContext
可以帮助程序员进行转换?@crush:这是一种可能性,但出于对可重入性的考虑,我仍然不推荐它。我有一份最近的报告,你可能会觉得有用。