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

ror*_*.ap 12 .net c# asynchronous console-application async-await

我在我的控制台应用程序中调用异步方法.我不希望应用程序在启动后立即退出,即在等待完成任务之前.好像我可以这样做:

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

internal static async Task DoThisAsync()
{
    //...
}
Run Code Online (Sandbox Code Playgroud)

但根据Stephen Cleary的文章,似乎我不能这样做,而应该创建某种上下文,让async在完成后返回(例如AsyncContext).

上面的代码可以工作,然后在主线程上返回Task.WaitAll(DoThisAsync());,为什么我需要使用自定义上下文?

Ste*_*ary 24

这不是必需的; 这只是我的偏好.

您可以同步阻止任务Main(使用Wait/ Result/ WaitAll).语义略有不同; 特别是,如果异步代码失败,那么Wait/ Result/ WaitAll将包装在一个异常AggregateException,而AsyncContext没有.

另外,AsyncContext特别对待主线程; 它不会向线程池发送延续,而是将它们发送回该主线程(默认情况下,您可以始终使用它ConfigureAwait(false)来避免这种情况).如果我正在编写一个"概念证明"控制台应用程序,我觉得这很有用,因为它的AsyncContext行为与UI上下文非常相似.

但在一天结束时,这只是一个偏好问题.

  • @crush:不,`AsyncContext`基本上作为一个消息循环,只有在完成所有异步操作后才会退出.在一般情况下,我不建议将其用作"结果"替换.在控制台的'Main`方法的情况下,使用`Result`或`AsyncContext`就好了; 在一般情况下,你应该使用`await`而不是`Result`,绝对不是'AsyncContext`. (2认同)