Подтвердить что ты не робот

Можно ли вызвать ожидаемый метод в неасинхронном методе?

В приложении Windows 8 в С#/XAML иногда я хочу вызвать ожидаемый метод из неасинхронного метода.

На самом деле правильно заменить это:

  public async Task<string> MyCallingMethod()
  {
      string result = await myMethodAsync();
      return result;
  }

:

   public string MyCallingMethod()
   {
       Task.Run(async () => {
            string result = await myMethodAsync();
            return result;
             });
   }

Преимущество для меня в том, что я могу использовать MyCallingMethod без ожидания, но это правильно? Это может быть преимуществом, если я хочу передать параметр ref для MyCallingMethod, поскольку невозможно использовать параметры ref в методе async.

4b9b3361

Ответ 1

В неасинхронном методе вы можете запускать задачу асинхронно и не дожидаться результата:

public void MyCallingMethod()
{
    Task t = myMethodAsync();
}

или вы можете присоединить ContinueWith обработчик событий, который вызывается после завершения задачи,

public void MyCallingMethod()
{
    myMethodAsync().ContinueWith(
        result =>
        {
            // do stuff with the result
        });
}

или вы можете получить результат из задачи синхронно:

public string MyCallingMethod()
{
    string result = myMethodAsync().Result;
    return result;
}

Ответ 2

Вам действительно не следует пытаться делать что-то подобное, если вы используете поток пользовательского интерфейса, потому что это будет означать, что вы заблокируете поток. Вместо этого вы должны обойти параметр ref, например, приняв параметр простого типа класса, который содержит значение, которое вы хотите изменить.

Другая причина, по которой это не делать, заключается в том, что она все еще не позволит вам использовать параметры ref, поскольку lambdas не может получить доступ к параметрам ref прилагаемого метода.

Но если вы действительно хотите это сделать (опять же, я действительно думаю, что вам не следует), вам нужно будет получить результат Task. Что-то вроде:

public string MyCallingMethod()
{
    var task = Task.Run(async () =>
    {
        return await myMethodAsync();
    });
    return task.Result;
}