如何在不等待的情况下在 C# 中安全地调用异步方法
- 作者: 零点深蓝8079911
- 来源: 51数据库
- 2023-02-08
问题描述
我有一个不返回数据的 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>
You should consider suppressing the warning only if you're sure that you don't want to wait for the asynchronous call to complete and that the called method won't raise any exceptions.
我确定我不想等待通话完成;我不需要也没有时间.但调用可能引发异常.
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#通过fleck实现wss协议的WebSocket多人Web实时聊天(附源码)
- 团队城市未满足要求:MSBuildTools12.0_x86_Path 存在
- 使用 MSBuild.exe 在发布模式下构建 C# 解决方案
- 当我发布 Web 应用程序时,AfterPublish 脚本不运行
- 构建时 T4 转换的产品仅在下一个构建中使用
- ASP.NET Core Application (.NET Framework) for Windows x64 only error in project.assets.json
- 新的 .csproj 格式 - 如何将整个目录指定为“链接文件"到子目录?
- 如何将条件编译符号(DefineConstants)传递给 msbuild
- MSBuild 支持 Visual Studio 2017 RTM 中的 T4 模板
- NuGet 包还原找不到包,没有源
