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 ?
The fact of marking
SearchPnrFilesAsync
withasync
keyword itself doesn't magically starts execution ot this method asynchronously in separate task.In fact, all of the code in
SearchPnrFilesAsync
exceptsw.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:
Probably because you have some blocking work done on the UI thread, such as reading a file.
Because that is not how
async
works. When youawait
a method, it asynchronously yields control to the caller until the operation is done. When the firstawait
is hit, you start reading files from disk and copying them.await
does not mean "execute this on a different thread and continue".What you probably want to do is use an asynchronous reading mechanism instead of the blocking
File.ReadAllText
. You can do this usingStreamReader
: