-1

I have a snippet that looks like this,

private void btn_Click(object sender, EventArgs e)
{
   try
   {
      var res = Task.Run(() => DoTask(param1, param2));
      if(res.IsCompleted)
      { 
          MessageBox.Show("Done");
      }
       MessageBox.Show("DoTask isn't called yet.");
   }
   catch
   {
       MessageBox.Show("Something wrong");
   }
}

The DoTask method looks like this

private async Task<bool> DoTask(int p1, int p2)
{
    // run long tasks   

}

I'd want to show Done message after the task is done. But this never works. Instead the message DoTask isn't called yet. is always called before DoTask does tasks.

Da Wei
  • 49
  • 4
  • 4
    Change the signature to `async void` and use `await`. Anything else would just freeze the UI, removing any benefit you'd get from `Task.Run` – Panagiotis Kanavos Mar 06 '20 at 17:41
  • I am wildly guessing you want to do something after task is complete without blocking current thread, see [this](https://stackoverflow.com/q/13211334/1997232). – Sinatr Mar 06 '20 at 17:42
  • 2
    Can you elaborate on why you are using `Task.Run` when `DoTask` is asynchronous? `Task.Run` should not be required in this case. – Thomas Barnekow Mar 06 '20 at 17:54
  • 1
    All of the answers posted thus far are dangerously wrong; they all produce situations in which you can easily deadlock your process. You do NOT get a result from a task without `await` *unless you already know that the task has completed*. Asynchronous tasks **need to be awaited asynchronously**. That's why they are asynchronous! – Eric Lippert Mar 06 '20 at 19:06

3 Answers3

0

Panagiotis' answer is the way to go. Should you have the same situation in a method that is not an event handler and you can't use async for some reason, here's the next best option:

Task<bool> task = Task.Run(() => DoTask(param1, param2));
bool res = task.GetAwaiter().GetResult();
Thomas Barnekow
  • 2,059
  • 1
  • 12
  • 21
0

To get Result from Task.Run without await

The proper way to get a result from an asynchronous task is to use await:

private async void btn_Click(object sender, EventArgs e)
{
   try
   {
      var res = await Task.Run(() => DoTask(param1, param2));
      if(res)
      { 
          MessageBox.Show("Done");
      }
       MessageBox.Show("DoTask isn't called yet.");
   }
   catch
   {
       MessageBox.Show("Something wrong");
   }
}

Note that you should usually avoid async void, but since this code is an event handler, the async void is OK.

Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810
-2

Simple Way:

bool result = DoTask(paran1, param2).Result;

No need to use Task.Run(). But you can use it in the following way (BAD WAY):

bool result = Task.Run(() => DoTask(paran1, param2).Result).Result;
Haddad
  • 301
  • 3
  • 5