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

В приложении Windows 8 на C#/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 в асинхронном методе.


person Thomas Salandre    schedule 13.09.2012    source источник
comment
не сработает. ваша анонимная асинхронная функция не будет возвращать значение внешней функции.   -  person Denis    schedule 15.09.2012


Ответы (2)


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

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;
}
person Martin Suchan    schedule 13.09.2012

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

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

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

public string MyCallingMethod()
{
    var task = Task.Run(async () =>
    {
        return await myMethodAsync();
    });
    return task.Result;
}
person svick    schedule 13.09.2012
comment
Хорошая, самостоятельная задача и возврат результата. Спасибо - person DRapp; 12.03.2017