问题描述
我有一个不返回数据的 async
方法:
I have an async
method which returns no data:
public async Task MyAsyncMethod()
{
// do some stuff async, don't return any data
}
我从另一个返回一些数据的方法调用它:
I'm calling this from another method which returns some data:
public string GetStringData()
{
MyAsyncMethod(); // this generates a warning and swallows exceptions
return "hello world";
}
调用 MyAsyncMethod()
而不等待它会导致 "因为没有等待这个调用,所以当前方法在调用完成之前继续运行"视觉工作室中的警告.在该警告的页面上,它指出:
Calling MyAsyncMethod()
without awaiting it causes a "Because this call is not awaited, the current method continues to run before the call is completed" warning in visual studio. On the page for that warning it states:
只有在确定不想等待异步调用完成并且被调用的方法不会引发任何异常时,才应考虑取消警告..p>
我确定我不想等待通话完成;我不需要也没有时间.但调用可能引发异常.
I'm sure I don't want to wait for the call to complete; I don't need to or have the time to. But the call might raise exceptions.
我偶然发现了这个问题几次,我确信这是一个常见的问题,必须有一个共同的解决方案.
I've stumbled into this problem a few times and I'm sure it's a common problem which must have a common solution.
如何在不等待结果的情况下安全地调用异步方法?
对于建议我只是等待结果的人,这是响应我们 Web 服务 (ASP.NET Web API) 上的 Web 请求的代码.在 UI 上下文中等待使 UI 线程保持空闲,但在 Web 请求调用中等待将等待任务完成后再响应请求,从而无缘无故地增加响应时间.
For people suggesting that I just await the result, this is code that is responding to a web request on our web service (ASP.NET Web API). Awaiting in a UI context keeps the UI thread free, but awaiting in a web request call will wait for the Task to finish before responding to the request, thereby increasing response times with no reason.
推荐答案
如果你想异步"获取异常,你可以这样做:
If you want to get the exception "asynchronously", you could do:
MyAsyncMethod().
ContinueWith(t => Console.WriteLine(t.Exception),
TaskContinuationOptions.OnlyOnFaulted);
这将允许您处理除主"线程之外的线程上的异常.线.这意味着您不必等待".用于从调用 MyAsyncMethod
的线程调用 MyAsyncMethod()
;但是,仍然允许您在异常情况下执行某些操作——但前提是发生异常.
This will allow you to deal with an exception on a thread other than the "main" thread. This means you don't have to "wait" for the call to MyAsyncMethod()
from the thread that calls MyAsyncMethod
; but, still allows you to do something with an exception--but only if an exception occurs.
从技术上讲,你可以用 await
做类似的事情:
technically, you could do something similar with await
:
try
{
await MyAsyncMethod().ConfigureAwait(false);
}
catch (Exception ex)
{
Trace.WriteLine(ex);
}
...如果您需要专门使用 try
/catch
(或 using
),这将很有用,但我发现 ContinueWith
更明确一点,因为您必须知道 ConfigureAwait(false)
表示.
...which would be useful if you needed to specifically use try
/catch
(or using
) but I find the ContinueWith
to be a little more explicit because you have to know what ConfigureAwait(false)
means.
这篇关于如何在不等待的情况下在 C# 中安全地调用异步方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!