一尘不染

如何在不等待的情况下安全地在C#中调用异步方法

c#

我有一个async不返回任何数据的方法:

public async Task MyAsyncMethod()
{
    // do some stuff async, don't return any data
}

我从另一个返回一些数据的方法中调用此方法:

public string GetStringData()
{
    MyAsyncMethod(); // this generates a warning and swallows exceptions
    return "hello world";
}

MyAsyncMethod()不等待的情况下进行调用会在Visual Studio中发出“
因为未等待此调用,因此当前方法会在调用完成之前继续运行 ”警告。在该警告的页面上,它指出:

仅当您确定不想等待异步调用完成并且 被调用的方法不会引发任何异常时 ,才应考虑禁止显示警告。

我确定我不想等待通话结束。我不需要或没有时间。 但是通话 可能会 引发异常。

我已经几次遇到这个问题,并且我确定这是一个常见的问题,必须有一个通用的解决方案。

如何安全地调用异步方法而不等待结果?

更新:

对于建议我只是等待结果的人,这是响应我们Web服务(ASP.NET Web
API)上的Web请求的代码。在UI上下文中等待将保持UI线程空闲,但是在Web请求调用中等待将等待Task完成,然后再响应请求,从而无故增加了响应时间。


阅读 386

收藏
2020-05-19

共1个答案

一尘不染

如果要“异步”获取异常,则可以执行以下操作:

  MyAsyncMethod().
    ContinueWith(t => Console.WriteLine(t.Exception),
        TaskContinuationOptions.OnlyOnFaulted);

这将使您可以处理“主”线程以外的线程上的异常。这意味着您不必“等待”
MyAsyncMethod()来自调用线程的调用MyAsyncMethod;但是,仍然允许您执行例外操作-但仅当发生例外时。

更新:

从技术上讲,您可以执行以下操作await

try
{
    await MyAsyncMethod().ConfigureAwait(false);
}
catch (Exception ex)
{
    Trace.WriteLine(ex);
}

…如果您需要专门使用try/
catch(或using),这将很有用,但我发现它ContinueWith要明确一些,因为您必须知道什么ConfigureAwait(false)意思。

2020-05-19