Kallol
Kallol

Reputation: 364

2 Async tasks in parallel and waiting for results - .Net

I intend to run two tasks in parallel and wait for both of them to finish. Here is my two tasks:

Private Async Function tempWorker1() As Task
    For i = 1 To 5000
        If i Mod 100 = 0 Then
            Console.WriteLine("From 1:{0}", i)
        End If
    Next
End Function

Private Async Function tempWorker2() As Task
    For i = 1 To 5000
        If i Mod 100 = 0 Then
            Console.WriteLine("From 2:{0}", i)
        End If
    Next
End Function

I run them as:

Dim task1 As Task = tempWorker1()
Dim task2 As Task = tempWorker2()
Await Task.WhenAll(task1, task2).ConfigureAwait(False)

However, I don't think the tasks are running in parallel.

Here is the output I get:

From 1:1000
From 1:2000
From 1:3000
From 1:4000
From 1:5000
From 2:1000
From 2:2000
From 2:3000
From 2:4000
From 2:5000

As you can see, it finishes task 1 and then task 2 finishes. I have increased the iterations near to positive infinity and checked - it is the same story.

How do we run these 2 tasks in parallel?

Upvotes: 0

Views: 134

Answers (1)

sstan
sstan

Reputation: 36523

Marking a method as Async only means that the method is now allowed to Await on one or many asynchronous operations within the method. But the keyword itself doesn't magically turn the method into an asynchronous one. In fact, because you don't await on anything within your tempWorker1 and tempWorker2 methods then your methods are in effect synchronous.

Supporting documentation: link

An async method typically contains one or more occurrences of an await operator, but the absence of await expressions doesn’t cause a compiler error. If an async method doesn’t use an await operator to mark a suspension point, the method executes as a synchronous method does, despite the async modifier. The compiler issues a warning for such methods.

Because marking a method with the Async keyword without awaiting on anything within the method is not useful, the compiler should have given you the following warning:

Warning This async method lacks 'Await' operators and so will run synchronously. Consider using the 'Await' operator to await non-blocking API calls, or 'Await Task.Run(...)' to do CPU-bound work on a background thread.


In this case, if you want to parallelize the work, you need to start them in separate threads. And one way to do this, is by calling Task.Run. Notice that, by using Task.Run, there really is no longer a need for your 2 methods to have the Async keyword set on them, or to even remain a function for that matter.

So you can accomplish your goal like this:

   Private Sub tempWorker1()
      For i = 1 To 5000
         If i Mod 100 = 0 Then
            Console.WriteLine("From 1:{0}", i)
         End If
      Next
   End Sub

   Private Sub tempWorker2()
      For i = 1 To 5000
         If i Mod 100 = 0 Then
            Console.WriteLine("From 2:{0}", i)
         End If
      Next
   End Sub

And then you execute the work in parallel like this:

  Dim task1 As Task = Task.Run(AddressOf tempWorker1)
  Dim task2 As Task = Task.Run(AddressOf tempWorker2)
  Await Task.WhenAll(task1, task2).ConfigureAwait(False)

Note: Even if coded properly, you may not observe the parallel execution as you would expect if the work performed by each tempWorkerX method is not too great. If the execution of the full method is able to execute within a single time slice or quantum, it may still appear as though one method executes and completes before the other even starts. Make sure that your tempWorkerX methods perform enough work for the parallelization to become noticeable.

Upvotes: 1

Related Questions