Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

await and async blocking the UI

I wrote a little winforms application that search for files on the disk (what file is not that important for the sake of the question). the problem is the that it can be even 100,000 files or so. so this operation takes time.

What I want to achieve is to do the search operation as an async operation and not to block the UI thread so the form won't get stuck.

I can do this with the backgroundWorker but for some reason not with the async\await mechanism.

Here is my code:

private async void button_FindFiles_Click(object sender, EventArgs e)
{
    await SearchFilesUtil.SearchPnrFilesAsync(this.textBox_mainDirectory.Text);
    MessageBox.Show("After SearchPnrFilesAsync");
}

public async static Task SearchPnrFilesAsync(string mainDir)
{
    foreach (string file in Directory.EnumerateFiles(mainDir, ".xml", SearchOption.AllDirectories))
    {
        var fileContenet = File.ReadAllText(file);
        var path = Path.Combine(@"C:\CopyFileHere", Path.GetFileName(file));
        using (StreamWriter sw = new StreamWriter(path))
        {
            await sw.WriteAsync(fileContenet);
        }
    }
}

Why is the UI thread get stuck and not displaying the MessageBox immediately? what am I missing ?

like image 734
Dardar Avatar asked Dec 08 '15 08:12

Dardar


People also ask

Does async await block UI thread?

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.

Is await async blocking?

await only blocks the code execution within the async function. It only makes sure that the next line is executed when the promise resolves. So, if an asynchronous activity has already started, await will not have an effect on it.

Does await block the 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.

Can async be blocking?

Making blocking calls to async methods transforms code that was intended to be asynchronous into a blocking operation. Doing so can cause deadlocks and unexpected blocking of context threads.


Video Answer


1 Answers

The fact of marking SearchPnrFilesAsync with async keyword itself doesn't magically starts execution ot this method asynchronously in separate task.

In fact, all of the code in SearchPnrFilesAsync except sw.WriteAsync executes in UI thread thus blocking it.

If you need to execute your whole method in separate task, you can do it by wrapping like:

public async static Task SearchPnrFilesAsync(string mainDir)
{
   await Task.Run(() => your_code_here);
}
like image 82
Andrey Korneyev Avatar answered Oct 22 '22 19:10

Andrey Korneyev