如何在异步方法起步并不期待已久的后台任务? [英] How do I start not-awaited background tasks in an async method?

查看:121
本文介绍了如何在异步方法起步并不期待已久的后台任务?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我和如何执行一些艰难的非常 - 长期运行在异步方法的世界后台处理。

使用的词汇斯蒂芬·克利里的博客,我感兴趣的是拉开了委托的任务后的 等待 -ing一个承诺的任务。我想,只要它的可用返回约定的价值,并让委托任务在后台继续运行。

要处理未例外 - 等待 -ed委托的任务,我将使用后的这里所描述的。

 公共异步任务< INT> ComplexProcessAsync()
{
  ...
  INT FIRSTRESULT =等待FirstStepAsync();  //编译器不喜欢这
  Task.Run(()=> VeryLongSecondStepIDontNeedToWaitFor(FIRSTRESULT))。LogExceptions();  返回FIRSTRESULT;
}

由于 VeryLongSecondStep ...()可能采取的多分钟,其结果是由副作用纯粹观察的(如出现在记录数据库),我的 reeeaaalllyy 的不想等待了。

但正如指出的那样,编译器不喜欢这样。它警告因为这个呼叫没有等待,呼叫结束之前,在当前的方法继续执行。考虑应用'等待'操作的调用的结果。

我可以不理会警告,但我得到我不是在正确的方式做这个的感觉。那么什么的的正确方法是什么?

谢谢!


解决方案

  

我可以不理会警告,但我得到我不是在正确的方式做这个的感觉。那么,什么是正确的方法是什么?


编译器警告你,你不等待的任务。从我的经验,>的99%的时间编译器是正确的,因为它缺少一个的await 的code是错误的。所以这是一个的罕见的,你知道你在做什么,想惊险的生活情况。 :)

在这种情况下,你可以明确的任务分配给一个未使用的变量:

  VAR _ = Task.Run(()=> VeryLongSecondStepIDontNeedToWaitFor(FIRSTRESULT));

编译器有足够的智能来了解您正在使用这个变量沉默失踪的await的警告。

在一个侧面说明,我不建议 ContinueWith 可言;在异步世界,它只是一个等待更危险的版本。所以我会写 LogExceptions 是这样的:

 公共静态异步任务LogExceptions(该任务的任务)
{
  尝试
  {
    等待task.ConfigureAwait(假);
  }
  赶上(异常前)
  {
    LogException(除息);
  }
}

I'm struggling with how to perform some very-long-running background processing in a world of async methods.

Using the vocabulary from Stephen Cleary's blog, I'm interested in kicking off a "delegate task" after await-ing a "promise task". I want to return the promised value as soon as it's available, and let the delegate task continue on in the background.

To handle exceptions in the un-await-ed delegate task, I'll use an exception-handling continuation modeled after 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;
}

Since VeryLongSecondStep...() could take many minutes, and its results are observable purely by side-effect (e.g. records appearing in a database), I reeeaaalllyy don't want to await it.

But as pointed out, the compiler doesn't like this. It warns "Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call."

I could ignore the warning, but I get the feeling I'm not doing this in "correct" way. So what is the correct way?

Thanks!

解决方案

I could ignore the warning, but I get the feeling I'm not doing this in "correct" way. So what is the correct way?

The compiler is warning you that you're not awaiting the task. From my experience, >99% of the time the compiler is correct, the code is wrong because it's missing an await. So this is one of the rare situations where you know what you're doing and want to live dangerously. :)

In this case, you can explicitly assign the task to an unused variable:

var _ = Task.Run(() => VeryLongSecondStepIDontNeedToWaitFor(firstResult));

The compiler is intelligent enough to understand that you're using this variable to silence the "missing await" warning.

On a side note, I do not recommend ContinueWith at all; in the async world, it's just a more dangerous version of await. So I'd write LogExceptions something like this:

public static async Task LogExceptions(this Task task)
{
  try
  {
    await task.ConfigureAwait(false);
  }
  catch (Exception ex)
  {
    LogException(ex);
  }
}

这篇关于如何在异步方法起步并不期待已久的后台任务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆