If I'm not mistaken, Task.Run create a new thread where the method should be executed.
Not really. Task.Run()
will run the code in a thread other than the user interface thread (at least by default TaskScheduler
). But in most cases, it will not actually create a new thread, it will reuse the existing thread from ThreadPool
.
Then why use the async method, if using Task, creating a new thread, I get what I want, so as not to block the main thread?
The async
point, in the context of the UI application, should be able to easily execute some code in the user interface thread after the asynchronous operation is completed.
So, if you made your method01Async
"expected", that is, made it return Task
:
private async Task method01Async() { await Task.Run(); }
Then you can wait for it from the btnAsync01_Click
method if you made it `async:
private async void btnAsync01_Click(object sender, RoutedEventArgs e) { UpdateTxtLog("click button: " + System.DateTime.Now); await method01Async(); UpdateTxtLog("after method01Async: " + System.DateTime.Now); }
Thus, the last line of the method will be executed only after the completion of the Task
in method01Async
. And it will execute in the user interface thread.
In .Net 4.0, you can achieve a similar effect with ContinueWith()
and Dispatcher.Invoke()
:
private void btnAsync01_Click(object sender, RoutedEventArgs e) { UpdateTxtLog("click button: " + System.DateTime.Now); method01Async().ContinueWith(() => Dispatcher.Invoke( new Action(() => UpdateTxtLog("after method01Async: " + System.DateTime.Now))); }
I am sure you will agree that this is a lot of messy and less readable.
Also, if the async method accesses some shared variable, I have to be careful with concurrency, right?
Yes, you are right about that.
In fact, I use the same code without async and without waiting, and the result is the same, the main program does not block, and everything works as I expect.
The result, of course, is not what I thought your code should do. The last line of btnAsync01_Click
will execute "after the 01Async method", but will not wait for the Task
to complete in this method.
As a side note, there is no need to use async
in method01Async
. Returning the Task
directly (or not, if you want to keep it void
-returning) will work the same way:
private Task method01Async() { return Task.Run(); }