代码之家  ›  专栏  ›  技术社区  ›  El Mac

链接任务并返回结果

  •  0
  • El Mac  · 技术社区  · 7 年前

    我有一个关于用第三方物流链接任务的问题。它必须与实体框架核心一起工作,因此我们不支持对同一数据库上下文的并发操作。

    我想要尽可能的异步。下面是代码 没有 异步:

    Context.Set<T>().Add(entity);
    Context.SaveChanges();
    return entity;
    

    我想让这个异步链接方法 AddAsync , SaveChangesAsync . 我必须确保 添加异步 在呼叫前完成 保存更改同步 .

    我的第一次尝试是:

    public Task<T> AddAsync(T entity)
    {
       return _dbContext.Set<T>()
              .AddAsync(entity)
              .ContinueWith(addTask =>
              {
                  _dbContext.SaveChangesAsync();
                  return addTask.Result.Entity;
              });
    }
    

    但我不认为这是正确的。 SaveChangesAsync() 不包含在返回的任务中。如果我打电话给: await AddAsync(myEntity); ,我确定 保存更改同步() 会结束吗?我不这么认为。

    所以我试图解决这个问题,但是我最终得到了嵌套的任务,这些任务对用户不太友好。可能的解决方案如下(伪代码,不编译):

    return Context.Set<T>()
                    .AddAsync(entity)
                    .ContinueWith(addTask =>
                    {
                        return Context.SaveChangesAsync()
                            .ContinueWith(saveTask =>
                            {
                                return addTask.GetAwaiter().GetResult().Entity;                            
                            });
                    });
    

    有没有办法使用第三方物流来实现这种行为?如果是的话:我只是在重新写作吗 await ? 这是一个应该在许多项目中使用的API。我想使API尽可能地具有性能(至少在理论上是这样)。我用它来学习)。用户应该使用 等待 在API之外。我要避免的是通过等待在API内部制造瓶颈。我不确定,如果 ContinueWith 不仅仅是 等待 . 另一件我在使用时避免的事情 继续 而不是 等待 就是把我的方法标记为 async .

    1 回复  |  直到 7 年前
        1
  •  1
  •   Camilo Terevinto Chase R Lewis    7 年前

    我不知道为什么 AddAsync 是实体框架核心的一部分,因为它只应将项添加到更改跟踪器(内存中),所以它不执行任何真正的异步操作。
    我甚至认为你不应该依赖它,因为有些驱动程序(比如MySQL官方)在调用时会死锁 添加异步 .

    如果需要实际的异步实现,只需使用:

    public async Task<T> AddAsync(T entity)
    {
        _dbContext.Set<T>().Add(entity);
        await _dbContext.SaveChangesAsync();
    
        return entity;
    }
    
    推荐文章