Search code examples
c#async-awaitout

How to write an async method with out parameter?


I want to write an async method with an out parameter, like this:

public async void Method1()
{
    int op;
    int result = await GetDataTaskAsync(out op);
}

How do I do this in GetDataTaskAsync?


Solution

  • You can't have async methods with ref or out parameters.

    Lucian Wischik explains why this is not possible on this MSDN thread: http://social.msdn.microsoft.com/Forums/en-US/d2f48a52-e35a-4948-844d-828a1a6deb74/why-async-methods-cannot-have-ref-or-out-parameters (Original post is no longer available due to link rot, latest archived version can be found here.)

    As for why async methods don't support out-by-reference parameters? (or ref parameters?) That's a limitation of the CLR. We chose to implement async methods in a similar way to iterator methods -- i.e. through the compiler transforming the method into a state-machine-object. The CLR has no safe way to store the address of an "out parameter" or "reference parameter" as a field of an object. The only way to have supported out-by-reference parameters would be if the async feature were done by a low-level CLR rewrite instead of a compiler-rewrite. We examined that approach, and it had a lot going for it, but it would ultimately have been so costly that it'd never have happened.

    A typical workaround for this situation is to have the async method return a Tuple instead. You could re-write your method as such:

    public async Task Method1()
    {
        var tuple = await GetDataTaskAsync();
        int op = tuple.Item1;
        int result = tuple.Item2;
    }
    
    public async Task<Tuple<int, int>> GetDataTaskAsync()
    {
        //...
        return new Tuple<int, int>(1, 2);
    }