【问题标题】:Fire and forget without async void没有异步无效的触发和忘记
【发布时间】:2017-01-17 22:11:07
【问题描述】:

我有三个方法,其中第一个结果将在接下来的两个方法中使用,并且不会返回任何数据。

 result= await DataAccess.Query(param); //Query 
    await DataAccess.Create(result);
    await DataAccess.Update(result);
  1. 我真的需要在这里使用 await 吗?

  2. 使用 async void 是否正确 在创建和更新功能中?

  3. 正确的做法是什么 一把火忘了这里?
  4. 如果我没有提到异步,它会火吗 然后忘了?
  5. async without await 的意义是什么? 只用于同步运行?我什至可以在没有那个关键字的情况下实现这一目标。

【问题讨论】:

  • 如果它是一劳永逸的,那你为什么要把响应分配给result?您可以使用Task.Run(()=> <your method>) 实现“一劳永逸”,甚至可以使用ContinueWith 链接它们。别忘了把ConfigureAwait(false)放在最后

标签: c# asp.net .net


【解决方案1】:

预计不会返回任何数据。

错误怎么办?如果发生错误,您是否需要返回错误代码,或者即使CreateUpdate 失败,200 OK 也可以接受?

我假设您需要一个错误代码。 99.99% 的电话都可以。

我真的需要在这里使用 await 吗?

好吧,如果您想要同步方法,那么您只需调用同步 API。不过,我不知道你为什么想要那个。

提醒一下:await 与返回浏览器无关。它与使用更少的线程池线程有关,从而使您的服务器可以进一步扩展。

在 create 和 update 函数中使用 async void 是否正确?

没有。从不。

在这里生火并忘记的正确方法是什么?

正确的做法是“不要”。即发即弃很难正确执行,事实上,由于您需要错误代码,所以您不能进行即发即弃。

我写了更多关于即发即弃的文章 - 包括为什么 StartNewTask.Run 是无效的解决方案 - on my blog。请注意,唯一完全可靠的解决方案(包括升级方案)是最后一个(分布式架构)。

如果只用于同步运行,那么没有等待的异步有什么意义?我什至可以在没有那个关键字的情况下实现这一目标。

串行(按顺序)运行,而不是同步(阻塞一个线程)。 async 的好处是允许更大的可扩展性。有关详细信息,请参阅我的 intro to async on ASP.NET 文章。

【讨论】:

    【解决方案2】:

    如果你需要按特定顺序调用多个方法,而这整套函数可以异步运行,我会这样做:

    Task.Run(() =>
    {
        result = Function();
        Create(result);
        Update(result);
    });
    

    这会将一组函数分离到新线程中。既然你没有在等待这个任务,那就是一劳永逸。

    如果你的函数被定义为异步,你可以像这样等待它们完成:

    Task.Run(() =>
    {
        var task = Function();
        task.Wait();
        var result = task.Result;
    
        Create(result).Wait();
        Update(result).Wait();
    });
    

    但是当您不打算从异步方法中受益时,最好覆盖您的方法以同步运行并使用第一个代码

    【讨论】:

      猜你喜欢
      • 2014-12-06
      • 1970-01-01
      • 2020-04-25
      • 2016-06-21
      • 2010-09-14
      • 2013-09-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多