我正在为如何在异步方法的世界中执行一些非常长时间运行的后台处理而苦苦挣扎。
使用 Stephen Cleary's blog 中的词汇,我有兴趣在 await
之后启动一个“委托(delegate)任务”-ing 一个“promise 任务”。我想尽快返回 promise 的值,让委托(delegate)任务在后台继续。
为了处理未await
委托(delegate)任务中的异常,我将使用以the one described here. 为模型的异常处理延续。
public async Task<int> ComplexProcessAsync()
{
...
int firstResult = await FirstStepAsync();
// THE COMPILER DOESN'T LIKE THIS
Task.Run(() => VeryLongSecondStepIDontNeedToWaitFor(firstResult)).LogExceptions();
return firstResult;
}
由于 VeryLongSecondStep...()
可能需要许多分钟,并且其结果纯粹是通过副作用(例如,记录出现在数据库中)观察到的,我 < em>reeeaaalllyy 不想等待
。
但正如所指出的,编译器不喜欢这样。它警告 “由于未等待此调用,因此在调用完成之前继续执行当前方法。考虑将 'await' 运算符应用于调用结果。”
我可以忽略警告,但我感觉我没有以“正确”的方式这样做。那么什么是正确的方法呢?
谢谢!
最佳答案
I could ignore the warning, but I get the feeling I'm not doing this in "correct" way. So what is the correct way?
编译器警告您您没有在等待任务。根据我的经验,>99% 的时间编译器是正确的,代码是错误的,因为它缺少 await
。因此,这是罕见情况之一,您知道自己在做什么并且想过危险的生活。 :)
在这种情况下,您可以显式地将任务分配给未使用的变量:
var _ = Task.Run(() => VeryLongSecondStepIDontNeedToWaitFor(firstResult));
编译器足够智能,可以理解您正在使用此变量来消除“缺少等待”警告。
附带说明一下,我根本不推荐 ContinueWith
;在异步世界中,它只是 await
的一个更危险的版本。所以我会这样写 LogExceptions
:
public static async Task LogExceptions(this Task task)
{
try
{
await task.ConfigureAwait(false);
}
catch (Exception ex)
{
LogException(ex);
}
}
关于c# - 如何在异步方法中启动未等待的后台任务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33834540/