Reputation: 364
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
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