为什么在控制台应用程序中使用 async/await 时需要 AsyncContext?
Why is AsyncContext needed when using async/await with a console application?
我正在我的控制台应用程序中调用一个异步方法。我不希望应用程序在启动后不久退出,即在等待任务完成之前退出。看来我可以做到:
internal static void Main(string[] args)
{
try
{
Task.WaitAll(DoThisAsync());
}
catch (Exception ex)
{
Console.Error.WriteLine(ex);
throw;
}
}
internal static async Task DoThisAsync()
{
//...
}
但根据Stephen Cleary's article it seems like I can't do that and should instead create some kind of context for the async to return to when it's done (e.g. AsyncContext).
虽然上面的代码有效,但它 returns 在 Task.WaitAll(DoThisAsync());
之后的主线程上,那么为什么我需要使用自定义上下文?
不需要;这只是我的偏好。
您可以在 Main
内同步阻止任务(使用 Wait
/Result
/WaitAll
)。语义略有不同;特别是,如果异步代码失败,则 Wait
/Result
/WaitAll
会将异常包装在 AggregateException
中,而 AsyncContext
则不会。
此外,AsyncContext
对主线程进行了特殊处理;它不会将延续发送到线程池,而是将它们发送回该主线程(默认情况下;您始终可以使用 ConfigureAwait(false)
来避免这种情况)。如果我正在编写 "proof of concept" 控制台应用程序,我发现这很有用,因为 AsyncContext
的行为与 UI 上下文非常相似。
但归根结底,这只是一个偏好问题。
我正在我的控制台应用程序中调用一个异步方法。我不希望应用程序在启动后不久退出,即在等待任务完成之前退出。看来我可以做到:
internal static void Main(string[] args)
{
try
{
Task.WaitAll(DoThisAsync());
}
catch (Exception ex)
{
Console.Error.WriteLine(ex);
throw;
}
}
internal static async Task DoThisAsync()
{
//...
}
但根据Stephen Cleary's article it seems like I can't do that and should instead create some kind of context for the async to return to when it's done (e.g. AsyncContext).
虽然上面的代码有效,但它 returns 在 Task.WaitAll(DoThisAsync());
之后的主线程上,那么为什么我需要使用自定义上下文?
不需要;这只是我的偏好。
您可以在 Main
内同步阻止任务(使用 Wait
/Result
/WaitAll
)。语义略有不同;特别是,如果异步代码失败,则 Wait
/Result
/WaitAll
会将异常包装在 AggregateException
中,而 AsyncContext
则不会。
此外,AsyncContext
对主线程进行了特殊处理;它不会将延续发送到线程池,而是将它们发送回该主线程(默认情况下;您始终可以使用 ConfigureAwait(false)
来避免这种情况)。如果我正在编写 "proof of concept" 控制台应用程序,我发现这很有用,因为 AsyncContext
的行为与 UI 上下文非常相似。
但归根结底,这只是一个偏好问题。