Async Method That Includes Async Call and Sync Act

2019-06-12 10:12发布

I am trying to make an async method that I can invoke multiple times and await later - the method should make a database call, await the results, do some manipulation once it has the results, and then return the final result. It looks like this:

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; 
}

This seems to be a clear mistake, since I am specifying the return type as Task, whereas I am actually returning just a long. This compiles, but throws an exception:

A first chance exception of type 'System.NotSupportedException' occurred in EntityFramework.dll

I plan to use this code like so:

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

This might be a bit irrelevant, but for elaboration, here is some good that works:

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

The difference, of course, is that it's just an async call to db, without further action, which I am trying to do in the SQL call I am asking the question about.

EDIT:

So, actually, this seems to be the offending line:

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

If I comment this out and set the count var manually, the code goes. I am pretty confused, but I am more interested in the overall question - whether or not I am using async correctly here, not necessarily the error to my particular bug.

1条回答
小情绪 Triste *
2楼-- · 2019-06-12 10:31

You cannot await multiple queries on the same context. You have to use an own context for each operation:

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;
        }
}
查看更多
登录 后发表回答