【问题标题】:Is it fine to await for one Task but not for other?等待一项任务而不是其他任务可以吗?
【发布时间】:2014-08-13 01:56:05
【问题描述】:

我有如下服务方法,

public async Task<IList<ProductsImage>> InsertAsync(BaseProduct product, Dictionary<string, Stream> images)
{
    try
    {
        if (images.Count > 0)
        {
            await _imageService.SaveAllAsync(images);
        }
        return await _repository.InsertAsync(product);
    }
    catch // Delete the files if there is an error from db
    {
        if (images.Count > 0)
        {
            var paths = images.Select(i => i.Key).ToList();
            _imageService.DeleteAllAsync(paths);                        
        }
        throw;
    }
}

问题是我不想在_imageService.DeleteAllAsync 等待,因为它需要一些时间才能完成,这样我就可以在不等待的情况下转移我的执行。在_imageService.DeleteAllAsync_imageService.DeleteAllAsync不使用await有什么危险

【问题讨论】:

  • 是的...如果出现问题,错误在哪里?
  • 如果您的进程在删除过程中退出(ASP.NET 工作进程一直在执行),则工作将丢失。
  • 是关于 ASP.NET 的问题吗?如果是这样,这已经在 SO 上多次出现,请检查 blogs.msdn.com/b/webdev/archive/2014/06/04/…blog.stephencleary.com/2014/06/fire-and-forget-on-asp-net.html。另一个(次要)问题是您将无法在 catch 中使用 await(直到下一个 C# 版本)。
  • spender 和 usr,意味着我需要另一个 try/catch 块吗?我可以在这里使用queuebackgroundworkitem吗,stackoverflow.com/questions/23978511/difference-between-hostingenvironment-queuebackgroundworkitem-and-hostingenviron
  • 除了未等待的任务之外,这为数据损坏铺平了道路。如果InsertAsync 的最终目标是数据库,为什么不利用数据库事务呢?或者,至少,执行插入以使对象处于“待处理”状态,根据您的业务规则,它们尚未被视为有效和可用,并运行原子更新以将它们标记为“可以使用” “在最后?

标签: c# async-await c#-5.0


【解决方案1】:

正确的方法是将此消息发送到消息队列,以便外部进程可以异步处理(无需等待)。这样,它还将保证 DeleteAllAsync 在失败时会被调用或重试。

这是我写的关于这个主题的文章的shameless plug

【讨论】:

    猜你喜欢
    • 2013-05-26
    • 1970-01-01
    • 2019-07-22
    • 1970-01-01
    • 2016-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多