Filipe G. Coelho
Filipe G. Coelho

Reputation: 114

Threads not working properly

I've the following code, used to test the Task framework on C#

  static void Main(string[] args)
  {
            Task<string> task1 = AsyncA();
            task1.ContinueWith(Print);

            Task<string> task2 = AsyncB();
            task2.ContinueWith(Print);

            Task.WaitAll(new Task[] {task1, task2});
   }

   static async Task<string> AsyncA()
   {
            Thread.Sleep(1500);
            return "A";
   }

   static async Task<string> AsyncB()
   {
            Thread.Sleep(430);
            return "B";
   }

   static async void Print(Task<string> str)
   {
            Console.WriteLine(str.Result);
   }

My output is the following:

A
B

What am I doing wrong? Thanks in advance.

Upvotes: 1

Views: 75

Answers (2)

Mong Zhu
Mong Zhu

Reputation: 23732

you are running the methods AsyncA and AsyncB synchronously. If you are using async you need to await the end of a task. Change your methods to

static async Task<string> AsyncA()
{
    await Task.Delay(1500);
    return "A";
}

static async Task<string> AsyncB()
{
    await Task.Delay(430);    
    return "B";
}

and you will get your expected output of

B
A

For further reference have a look on the MSDN example

EDIT:

For the sake of completeness you should also change the Print method in the same manner, otherwise it also is running synchronously up to now.
Since in this method you get the task via the parameter you can actually await the result directly in the Console.WriteLine method:

static async void Print(Task<string> str)
{
    Console.WriteLine(await str);
}

Upvotes: 9

Nathangrad
Nathangrad

Reputation: 1464

Firstly, when using asynchronous methods, it's generally more accepted to use the awaitable Task.Delay(ms) rather than Thread.Sleep(ms).

In the MSDN documentation, the ContinueWith(task) method:

Creates a continuation that executes asynchronously when the target Task completes.

For this reason, only once task1 is completed, it will execute the remainder of the code - this is why your ouput is A B rather than B A.

By using Task.Delay(ms) and awaiting the methods as opposed to using ContinueWith(task), you'll get your expected output.

Upvotes: 2

Related Questions