Reputation: 7361
I am sure this question has been asked in many forms before, but I am struggling to find something to clarify my understanding.
As far as I understand it, the concept of asynchronously
running certain sections of code in .Net is based around sending work off into multiple threads so that it can run in parallel with other work. In some cases we need to wait for this work to be finished before we can get on with the next thing and in others we don't. I am mainly confused about how to handle these differences.
There are various analogies I can use, but let's look at a builder, or team of builders building a house. At various stages the team are working together on separate tasks, or together on one, here's a very simplified walk-through.
In this analogy, we have three types of Task
;
I found this question on SO:
How to put this function inside a separate thread
It is quite helpful, mainly the response from "igrimpe", I will copy his code:
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
' fire and forget:
Task.Run(Sub() FooA()).ContinueWith(Sub() FooB()).ContinueWith(Sub() FooC())
Console.WriteLine("Button1 done")
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
' fire and forget:
Task.Run(Sub()
FooA()
FooB()
FooC()
End Sub)
Console.WriteLine("Button2 done")
End Sub
Private Async Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
' wait but dont block:
Await Task.Run(Sub()
FooA()
FooB()
FooC()
End Sub)
Console.WriteLine("Button3 done")
End Sub
Private Sub FooA()
Threading.Thread.Sleep(1000)
Console.WriteLine("A")
End Sub
Private Sub FooB()
Threading.Thread.Sleep(1000)
Console.WriteLine("B")
End Sub
Private Sub FooC()
Threading.Thread.Sleep(1000)
Console.WriteLine("C")
End Sub
End Class
Where he says "fire and forget", I think that is my Postcode analogy, and "wait but don't block" is the Electricians and Plumbers? Am I right that in his example code these jobs will run separately each on their own CPU thread?
Can someone help with code that explicitly outlines the cases I mention above, especially identifying when separate or multiple tasks are finished, either together or individually and ensuring that I understand how to fire tasks to which I do not need a response.
Additionally
This function:
Public Async Sub Report(Message As String)
Task.Run(Sub() Write(Message) )
End Sub
Gives me two warnings from Visual Studio:
and
They seem to contradict each other, on the main Sb
declaration it is saying this will run synchronously, but where I am declaring a Task
it says that because there is no await
the method will continue running before the task may be complete - which in this case (fire and forget) I don't care about. Adding Await
before run fixes this warning, but I am unclear as to whether this is truly a fire and forget now?
Upvotes: 0
Views: 62
Reputation: 330
I'll try to explain the difference between Sync and Async using another analogy.
We need to make a breakfast. Our breakfast is made by these tasks:
Each task can be unattended
Sync approch will be:
Total task time 5 min
Async approch:
Total task time 3 min
If we need to scale the number of breakfasts we can multiply everything by the number of breakfast needed (No concurrency). Or we can increase the number of people working on it (Threads Concurrency)
Upvotes: 2
Reputation: 51
I can only answer this question by my C# knowlege :D ... You actually got all of your cases right.
Public Async Sub Report(Message As String)
Task.Run(Sub() Write(Message) )
End Sub
This code will do the fire and forget approach. You could just ignore the warning. It is as designed.
I think you could even remove the Async keyword here. You don't want to await for anything here. That could clear the first warning.
If you would change the code like this the execution would be synchronously because you wait until the task has finished it's execution:
Public Async Sub Report(Message As String)
Await Task.Run(Sub() Write(Message) )
End Sub
The only difference between calling just Write(Message) without executing it in an awaited task would be that your GUI would stay freezed until the Write function has been finished.
Upvotes: 1