c# - 如何在异步方法中启动未等待的后台任务?

标签 c# .net async-await

我正在为如何在异步方法的世界中执行一些非常长时间运行的后台处理而苦苦挣扎。

使用 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/

相关文章:

c# - 以毫秒为单位测量 .net 中的代码速度

C# 从数组返回对象留下指向数组项的指针

c# - 捕捉/粘性 WPF 窗口

JavaScript 无法识别 Controller

c# - 使用 IAppBuilder.UseWebApi 时出现问题

c# - 使用 List<string> 替换字符串

javascript - array.push 没有根据序列推送对象,而某些对象使用等待执行操作

javascript - 有没有办法将 await/async try/catch block 包装到每个函数?

c# - 如何在没有 AsyncEx 库的情况下调用 anglesharp 异步方法?

c# - CryptFindLocalizedName 在多次调用时返回无效字符串