Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can you await a Task when you can't await

I'm developing a Windows 8 Runtime Component so the public interface can't contain Task<T> as it's not a windows runtime type.

This means I can't mark the method as async and can't await the private async methods in my library. This is leading to some confusion about how to handle my application logic.

This is how I'd do what I want synchronously.

Result r = TryGetAuthResultFromFile();
if(r != null)
{
    return r;
}

r = GetAuthResultFromWebAuthenticationBroker();
return r;

The problem is that TryGetResultFrom file are async Task<Result> methods and the method that's returning r is returning IAsyncOperation<Result>

I've tried this (this isn't complete code but the theory can be seen, handle the results in continuations and return them, I'd have to do some frigging of results to IAsyncOperation types).

TryGetAuthResultFromFile().ContinueWith(x=>
{
    if(x.Result != null)
    {
        return x.result;
    }

    GetAuthResultFromWebAuthenticationBroker().ContinueWith(y=>
    {
        return y.Result;
    });
});

The problem with this is that the WebAuthenticationBroker doesn't seem work if it's not being called from the UI thread. It throws a helpful NotImplementedException without a useful error message.

How can I call TryGetAuthResultFromFile then wait for the result, then call GetAuthResultFromWebAuthenticationBroker?

like image 505
BenCr Avatar asked Nov 28 '12 16:11

BenCr


1 Answers

Your interface can't use Task/Task<T>, but it can use IAsyncAction/IAsyncOperation<T>.

Your implementation can use Task/Task<T> if you have a wrapper that calls AsAsyncAction/AsAsyncOperation/AsyncInfo.Run as appropriate.

public interface IMyInterface
{
  IAsyncOperation<MyResult> MyMethod();
}

public sealed class MyClass: IMyInterface
{
  private async Task<MyResult> MyMethodAsync()
  {
    var r = await TryGetAuthResultFromFileAsync();
    if (r != null)
      return r;
    return await GetAuthResultFromAuthenticationBrokerAsync();
  }

  public IAsyncOperation<MyResult> MyMethod()
  {
    return MyMethodAsync().AsAsyncOperation();
  }
}
like image 67
Stephen Cleary Avatar answered Oct 22 '22 11:10

Stephen Cleary