PeterLiguda
PeterLiguda

Reputation: 792

Async Func in C# - correct async await usage

I want to simplify out repository code and want to use Funcs to provide common functionality. The problem now is based on this code:

namespace Test
{
    public class Demo
    {

        public Task<Person> GetAsync1(Guid id)
        {
            return ExecuteAsync(context => context.Persons.GetAsync(id));
        }

        public async Task<Person> GetAsync2(Guid id)
        {
            return await ExecuteAsync(async context => await context.Persons.GetAsync(id));
        }

        public Task<Person> GetAsync3(Guid id)
        {
            return ExecuteAsync(async context => await context.Persons.GetAsync(id));
        }

        public Task<TOut> ExecuteAsync(Func<Context, Task<TOut>> func)
        {
            using(var context = new Context())
            {
                return func(context);
            }
        }
    }

}

The problem here for me is now how to call the async func correctly. Which of those three Get methods is correct? With the first one I think I get a deadlock because it hangs at this point. Number 2 works fine but I think two async/awaits here are not correct, because of the Task re-wrapping!?

Upvotes: 3

Views: 266

Answers (1)

Scott Chamberlain
Scott Chamberlain

Reputation: 127603

Actually all 3 GetAsync implmentations where fine to do (personally I would use GetAsync1), what you have is a bug in ExecuteAsync

public async Task<TOut> ExecuteAsync(Func<Context, Task<TOut>> func)
{
    using(var context = new Context())
    {
        return await func(context);
    }
}

By awaiting the output of func you do not dispose of the context until the function has completed it's work.

Upvotes: 8

Related Questions