How do I wait until Task is finished in C#?

149,115

Solution 1

Your Print method likely needs to wait for the continuation to finish (ContinueWith returns a task which you can wait on). Otherwise the second ReadAsStringAsync finishes, the method returns (before result is assigned in the continuation). Same problem exists in your send method. Both need to wait on the continuation to consistently get the results you want. Similar to below

private static string Send(int id)
{
    Task<HttpResponseMessage> responseTask = client.GetAsync("aaaaa");
    string result = string.Empty;
    Task continuation = responseTask.ContinueWith(x => result = Print(x));
    continuation.Wait();
    return result;
}

private static string Print(Task<HttpResponseMessage> httpTask)
{
    Task<string> task = httpTask.Result.Content.ReadAsStringAsync();
    string result = string.Empty;
    Task continuation = task.ContinueWith(t =>
    {
        Console.WriteLine("Result: " + t.Result);
        result = t.Result;
    });
    continuation.Wait();  
    return result;
}

Solution 2

It waits for client.GetAsync("aaaaa");, but doesn't wait for result = Print(x)

Try responseTask.ContinueWith(x => result = Print(x)).Wait()

--EDIT--

Task responseTask = Task.Run(() => { 
    Thread.Sleep(1000); 
    Console.WriteLine("In task"); 
});
responseTask.ContinueWith(t=>Console.WriteLine("In ContinueWith"));
responseTask.Wait();
Console.WriteLine("End");

Above code doesn't guarantee the output:

In task
In ContinueWith
End

But this does (see the newTask)

Task responseTask = Task.Run(() => { 
    Thread.Sleep(1000); 
    Console.WriteLine("In task"); 
});
Task newTask = responseTask.ContinueWith(t=>Console.WriteLine("In ContinueWith"));
newTask.Wait();
Console.WriteLine("End");

Solution 3

A clean example that answers the Title

string output = "Error";
Task task = Task.Factory.StartNew(() =>
{
    System.Threading.Thread.Sleep(2000);
    output = "Complete";
});

task.Wait();
Console.WriteLine(output);
Share:
149,115
Admin
Author by

Admin

Updated on October 28, 2020

Comments

  • Admin
    Admin over 3 years

    I want to send a request to a server and process the returned value:

    private static string Send(int id)
    {
        Task<HttpResponseMessage> responseTask = client.GetAsync("aaaaa");
        string result = string.Empty;
        responseTask.ContinueWith(x => result = Print(x));
        responseTask.Wait(); // it doesn't wait for the completion of the response task
        return result;
    }
    
    private static string Print(Task<HttpResponseMessage> httpTask)
    {
        Task<string> task = httpTask.Result.Content.ReadAsStringAsync();
        string result = string.Empty;
        task.ContinueWith(t =>
        {
            Console.WriteLine("Result: " + t.Result);
            result = t.Result;
        });
        task.Wait();  // it does wait
        return result;
    }
    

    Am I using Task correctly? I don't think so because the Send() method returns string.Empty every time, while Print returns the correct value.

    What am I doing wrong? How do I get the correct result from a server?

  • Admin
    Admin over 11 years
    But I call task.Wait() within Print() method.
  • L.B
    L.B over 11 years
    When you call task.Wait() you wait the original Task, not the one you created with ContinueWith
  • Kenneth Ito
    Kenneth Ito over 11 years
    As an aside, the pattern where you call async and then immediately wait on it, is pretty much the same as just calling synchronously.
  • Admin
    Admin over 11 years
    Why don't you call responseTask.Wait() before newTask.Task()?
  • Kiquenet
    Kiquenet over 10 years
    for not console application ? not Readline available, any solution?
  • Sinatr
    Sinatr about 8 years
    @OskarK., there is no need to wait for previous task. ContinueWith will guarantee previous task is completed.
  • Vidiya Prasanth Pappannan
    Vidiya Prasanth Pappannan over 6 years
    This is the best solution when u are stuck with .net Framework 4.0 and you have problems adding microsoft.bcl.async nuget pkg inorder to use Await.
  • Yesyoor
    Yesyoor over 2 years
    Thanks, this helped me to work out my solution.