【问题标题】:Async Method That Includes Async Call and Sync Action on Result包括异步调用和结果同步操作的异步方法
【发布时间】:2016-06-21 05:50:24
【问题描述】:

我正在尝试创建一个可以多次调用并稍后等待的异步方法 - 该方法应该进行数据库调用,等待结果,在获得结果后进行一些操作,然后返回最终结果。它看起来像这样:

public async Task<long> GetSomethingFromDbAndSelectSomethingOnServer()
{
        //stuff is just an Entity Framework database call 
        var stuff = await myEfDbContext.StuffTable.ToListAsync();                     
        long itemsCount = stuff.Where(someQueryThatCantGoToDb).Count();
        return itemsCount; 
}

这似乎是一个明显的错误,因为我将返回类型指定为任务,而实际上我只返回一个 long。这会编译,但会引发异常:

“System.NotSupportedException”类型的第一次机会异常 发生在EntityFramework.dll中

我打算这样使用这段代码:

Task<long> myAsyncCall = GetSomethingFromDbAndSelectSomethingOnServer();
long myCount = await myAsyncCall;

这可能有点无关紧要,但为了详细说明,这里有一些有用的东西:

Task<long> pendingItemCountCall =  _mongoItems.Find(filter).CountAsync();
long myCount2 = await pendingItemCountCall;

当然,不同之处在于它只是对 db 的异步调用,没有进一步的操作,我试图在我提出的问题的 SQL 调用中执行此操作。

编辑:

所以,实际上,这似乎是违规行:

var stuff = await myEfDbContext.StuffTable.ToListAsync();  

如果我将其注释掉并手动设置 count var,代码就会运行。我很困惑,但我对整个问题更感兴趣——我是否在这里正确使用异步,不一定是我的特定错误的错误。

【问题讨论】:

  • @HenkHolterman:成功了!!

标签: c# entity-framework asynchronous


【解决方案1】:

您不能在同一上下文中等待多个查询。您必须为每个操作使用自己的上下文:

public async Task<long> GetSomethingFromDbAndSelectSomethingOnServer()
{
        using(var context = new MyEfDbContext())
        {
            // include the following if you do not need lazy loading and want some more speed
            context.Configuration.AutoDetectChangesEnabled = false;
            context.Configuration.ProxyCreationEnabled = false;

            var stuff = await myEfDbContext.StuffTable.ToListAsync();                     
            long itemsCount = stuff.Where(someQueryThatCantGoToDb).Count();
            return itemsCount;
        }
}

【讨论】:

  • 感谢您的回答,我在这里看到:stackoverflow.com/questions/20946677/…,我会检查并接受答案,如果它有效,虽然似乎有一些如果和但是。
  • 那个答案是 2 岁。到目前为止,EF 和 ASP 都可以正常使用 async/await。对于 ASP,你只需要知道在 ConfigureAwait(false) 之后你会丢失 HttpContext.Current,所以如果你需要 HttpContext.Current,你不能使用 ConfigureAwait(false)。
  • 在将它包装到 using 语句(使用实体框架)后仍然失败,但我会继续寻找。鼓励听到它应该工作,将继续搞砸它。我确实认为这是问题所在,因为它在我只调用一次时工作,并且在多次调用时只会在后续迭代中失败。
  • 我每天都在使用这种模式,所以我很确定 ;) 如果您仍有问题,请随时发布完整的异常(带消息)。
  • 工作,我忘了将数据库上下文更改为我在使用中创建的那个(我知道,我很喜欢哈哈)。非常感谢你,很高兴你在身边。打算把这个问题和旧问题联系起来,因为我已经准备好放弃了。
猜你喜欢
  • 2016-05-14
  • 1970-01-01
  • 2016-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-19
相关资源
最近更新 更多