I'm working with .Net Core 5.0 and Dapper as ORM.
I have the following c# code:
    public Task<IEnumerable<FooViewModel>> FetchAllFoos1(CancellationToken cancel = default)
    {
        string sql = "SELECT * FROM Foos";
        var context = new DbContext();
        var connection = context.GetConnection();
        var cmd = new CommandDefinition(sql, cancellationToken: cancel);
        return connection.QueryAsync<Foo>(cmd)
            .ContinueWith(x => x.Result.Select(y => ToFooViewModel(y)), cancel);
    }
This code is working perfectly.
But this one not and I don't understand why:
    public Task<IEnumerable<FooViewModel>> FetchAllFoos2(CancellationToken cancel = default)
    {
        string sql = "SELECT * FROM Foos";
        using (var context = new DbContext())
        {
            using (var connection = context.GetConnection())
            {
                 var cmd = new CommandDefinition(sql, cancellationToken: cancel);
                 return connection.QueryAsync<Foo>(cmd)
                        .ContinueWith(x => x.Result.Select(y => ToFooViewModel(y)), cancel);
            }
        }
    }
When awaiting the result of FetchAllFoos2: var result = await FetchAllFoos2(), i have a Task Cancelled exception. It happens in the ContinueWith, when it's trying to get x.Result.
I know that the issue come from because i'm using "using" that close the context/connection, but i don't undestand the inner reasons of the exception. I like to use "using" to make sure that any disposable object is cleaned when i'm over the control of the using, but it seems that i cannot use it here..
Can you help me to understand ?
Thank you.
                        
As TheGeneral pointed out, the core problem is that you're using the dangerous, low-level
ContinueWithmethod. As a general rule, useawaitinstead ofContinueWith.One of the problems of skipping
asyncandawaitis that things like disposal happen at an incorrect time. For theasyncmethod, the disposals happen after the data is retrieved (after theawait). For the non-asyncmethod, the disposals happen after the query is started but (possibly) before it returns its data.