Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

await keyword blocks main thread

Tags:

So I have the following code

private async void button1_Click(object sender, EventArgs e) {     await DoSomethingAsync();      MessageBox.Show("Test"); }  private async Task DoSomethingAsync() {     for (int i = 0; i < 1000000000; i++)     {         int a = 5;     }; // simulate job      MessageBox.Show("DoSomethingAsync is done");      await DoSomething2Async(); }  private async Task DoSomething2Async() {     for (int i = 0; i < 1000000000; i++)     {         int a = 5;     } // simulate job      MessageBox.Show("DoSomething2Async is done"); } 

Until both MessageBoxes are shown the main thread is block (I mean the application itself is frozen). There is obviously something wrong with my code and I can't figure out what. I've never used async/await before. this is my first attempt.

EDIT:

Actually what i want to do is to start Execution of DoSomethingAsync asynchronously so that when button is clicked the MessageBox.Show("Test"); would execute even though the DoSomethingAsync is incomplete.

like image 896
Dimitri Avatar asked Nov 06 '13 13:11

Dimitri


People also ask

Does await block the main thread?

Because await is only valid inside async functions and modules, which themselves are asynchronous and return promises, the await expression never blocks the main thread and only defers execution of code that actually depends on the result, i.e. anything after the await expression.

Does await block calling thread?

The await operator doesn't block the thread that evaluates the async method. When the await operator suspends the enclosing async method, the control returns to the caller of the method.

Is await keyword blocked?

The await keyword, by contrast, is non-blocking, which means the current thread is free to do other things during the wait.

Does async await block main thread JavaScript?

Though it creates a confusion, in reality async and await will not block the JavaScript main thread. Like mentioned above they are just syntactic sugars for promise chaining.


1 Answers

I think you misunderstand what async means. It doesn't mean that the method runs in another thread!!

An async method runs synchronously until the first await, then returns a Task to the caller (unless it's async void, then it returns nothing). When the task that is being awaited completes, execution resumes after the await, usually on the same thread (if it has a SynchronizationContext).

In your case, the Thread.Sleep is before the first await, so it's executed synchronously, before control is returned to the caller. But even if it was after the await, it would still block the UI thread, unless you specifically configured the the awaiter not to capture the synchronization context (using ConfigureAwait(false)).

Thread.Sleep is a blocking method. If you want an async equivalent, use await Task.Delay(3000), as suggested in Sriram Sakthivel's answer. It will return immediately, and resume after 3 seconds, without blocking the UI thread.

It's a common misconception that async is related to multithreading. It can be, but in many cases it's not. A new thread is not implicitly spawned just because the method is async; for a new thread to spawn, it has to be done explicitly at some point. If you specifically want the method to run on a different thread, use Task.Run.

like image 117
Thomas Levesque Avatar answered Oct 05 '22 13:10

Thomas Levesque