0

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.

VSO
  • 11,546
  • 25
  • 99
  • 187

1 Answers1

3

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;
        }
}
wertzui
  • 5,148
  • 3
  • 31
  • 51
  • Thanks for the answer, I am seeing that here: http://stackoverflow.com/questions/20946677/ef-data-context-async-await-multithreading, I will check that and accept the answer if it works, though there seem to be some ifs and buts. – VSO Mar 07 '16 at 15:53
  • 1
    That answer is 2 years old. Both EF and ASP are working fine with async/await as of today. For ASP you just have to know that you will loose HttpContext.Current after ConfigureAwait(false), so if you need HttpContext.Current you must not use ConfigureAwait(false). – wertzui Mar 07 '16 at 15:58
  • It's still failing for me after wrapping it into a using statement (using Entity Framework), but I will keep looking. Encouraging to hear that it should work, will keep messing with it. I do think that's the problem, as it was working when I was only calling it once, and only fails on subsequent iterations when called multiple times. – VSO Mar 07 '16 at 16:00
  • I'm using this pattern every day, so I'm quite sure ;) Feel free to post the complete exception (with message) if you are still haveing problems. – wertzui Mar 07 '16 at 16:11
  • Worked, I forgot to change db context to the one I created in the using (I know, I am so pro lol). Thank you very much, very happy you were around. Going to link this question in the old one, because I was ready to give up. – VSO Mar 07 '16 at 16:21