Как вы можете ждать задания, если вы не можете ждать

Я разрабатываю компонент Runtime Windows 8, поэтому открытый интерфейс не может содержать Task<T>, поскольку он не является типом времени выполнения Windows.

Это означает, что я не могу отметить метод как async и не может await методы private async в моей библиотеке. Это приводит к некоторой путанице в том, как обращаться с моей логикой приложения.

Вот как я буду делать то, что хочу синхронно.

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

r = GetAuthResultFromWebAuthenticationBroker();
return r;

Проблема заключается в том, что файл TryGetResultFrom - это методы async Task<Result>, и возвращаемый метод возвращает IAsyncOperation<Result>

Я пробовал это (это не полный код, но теория может быть замечена, обрабатывать результаты в продолжениях и возвращать их, я должен был бы сделать некоторые ошибки в типах IAsyncOperation).

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

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

Проблема заключается в том, что WebAuthenticationBroker не работает, если он не вызывается из потока пользовательского интерфейса. Он выдает полезный NotImplementedException без полезного сообщения об ошибке.

Как я могу вызвать TryGetAuthResultFromFile, а затем дождаться результата, а затем вызвать GetAuthResultFromWebAuthenticationBroker?

Ответ 1

Ваш интерфейс не может использовать Task/Task<T>, но он может использовать IAsyncAction/IAsyncOperation<T>.

В вашей реализации может использоваться Task/Task<T>, если у вас есть обертка, которая вызывает AsAsyncAction/AsAsyncOperation/AsyncInfo.Run, если это необходимо.

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();
  }
}