I want to do something asynchronously and don't care for the result.
What is the best way to do that?
Public Async Function HandlerForSomeEvent() As Task
'This is where I do stuff
'Then this is stuff I want to do without waiting for it
DoStuff()
'Here I continue doing other stuff
End Function
Async Sub DoStuff()
'Doing stuff while the handler continues doing it's stuff
End Sub
'VS
Async Function DoStuff() As Task
'Doing stuff while the handler continues doing it's stuff
End Function
Everyone tells me to use Function As Task
, but as I don't await it I always get the annoying warning in VS.
What is the difference and why should I do it?
The big reasons for using a Function
that returns a Task
, rather than an Async Sub
are two-fold. The first is exception handling. If you do something like this, you'll get an uncaught exception which will terminate your application:
Public Sub Main()
Try
DoSomethingAsync()
Catch ex As Exception
Console.WriteLine(ex)
End Try
End Sub
Private Async Sub DoSomethingAsync()
Throw New Exception()
End Sub
The exception won't get caught by the Try/Catch block, since it's thrown on a separate thread.
However, if you do this, it will get caught and handled:
Public Async Sub Main()
Try
Await DoSomethingAsync()
Catch ex As Exception
Console.WriteLine(ex)
End Try
End Sub
Private Async Function DoSomethingAsync() As Task
Throw New Exception()
End Sub
The second big reason is because, even though you might not need it now, you might need it later. If it's already a function that returns a task, then you can use it either way you wish. If you don't, you can't await on it, or schedule things to happen after it, or abort it, or do any of the other things that you can do with tasks. So, the question really isn't "why do it?", but rather "why not do it?"
For instance, this outputs "Here" followed by "Done":
Public Sub Main()
DoSomethingAsync()
Threading.Thread.Sleep(5000)
Console.WriteLine("Done")
End Sub
Public Async Function DoSomethingAsync() As Task
Console.WriteLine("Here")
End Function
As others have mentioned, to avoid the warning, you can assign the task to a variable like this:
Public Sub Main()
Dim t As Task = DoSomethingAsync()
Threading.Thread.Sleep(5000)
Console.WriteLine("Done")
End Sub
It works the same either way and runs on its own thread, just like an Async Sub
. It doesn't matter if the Task
variable goes out of scope either. The task will continue running even if nothing is referencing it. For instance:
Public Sub Main()
DoSomething()
Threading.Thread.Sleep(5000)
Console.WriteLine("Really Done")
End Sub
Public Sub DoSomething()
Dim t As Task = DoSomethingAsync()
Console.WriteLine("Done Doing Something")
End Sub
Public Async Function DoSomethingAsync() As Task
Console.WriteLine("Here")
End Function
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With