40

In a windows 8 application in C#/XAML, I sometimes want to call an awaitable method from a non asynchronous method.

Actually is it correct to replace this :

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

by this :

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

The advantage for me is that I can use MyCallingMethod without await but is this correct? This can be an advantage if I want to pass a ref parameter for MyCallingMethod since It is not possible to have ref parameters in an async method.

cuongle
  • 74,024
  • 28
  • 151
  • 206
Thomas Salandre
  • 817
  • 3
  • 14
  • 27

2 Answers2

65

In non-async method you can either start the Task asynchronously and not wait for the result:

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

or you can attach ContinueWith event handler, which is called after finishing the Task,

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

or you can get the result from the Task synchronously:

public string MyCallingMethod()
{
    string result = myMethodAsync().Result;
    return result;
}
Martin Suchan
  • 10,600
  • 3
  • 36
  • 66
26

You really shouldn't try to do something like that if you're on the UI thread, because that will mean you will block the thread. You should instead work around the ref parameter, for example by accepting a parameter of a simple class type, that contains the value you want to change.

Another reason why not to do this is that it still won't let you use ref parameters, because lambdas can't access ref parameters of the enclosing method.

But if you really want to do this (again, I really think you shouldn't), then you will need to get the result of the Task. Something like:

public string MyCallingMethod()
{
    var task = Task.Run(async () =>
    {
        return await myMethodAsync();
    });
    return task.Result;
}
svick
  • 236,525
  • 50
  • 385
  • 514
  • Nice, self-resolved task and return the result. Thanks – DRapp Mar 12 '17 at 12:04
  • 1
    Does this avoid the deadlock that would occur by having the main thread block on .Result or Wait()? What's the difference between what you have and calling `var res = myMethodAsync().Result` – Stack Undefined Sep 06 '22 at 03:07