I have problem with async/await method of mine. I am new into async/await and seems I can't get it to work correctly.
The GUI freezes when I have the following.
private async void SetUpTextBox(string s)
{
//This method is called in button event
string textToSet = await GetTextA(s);
read_Box.Text = textToSet;
}
private Task<string> GetTextA(string s)
{
return Task.Run(() => GetText(s));
}
private string GetText(string s)
{
string textToReturn = "Hello";
using (StreamReader sr = new StreamReader(File.OpenRead(s)))
{
textToReturn = sr.ReadToEnd();
}
return textToReturn;
}
I don't know what I am doing wrong. I know I am new into this and that's why I am here to learn (a.k.a don't judge!).
P.S When I tried to change
using (StreamReader sr = new StreamReader(File.OpenRead(s)))
{
textToReturn = sr.ReadToEnd();
}
With simple Thread.Sleep(2500)
method. The GUI doesn't freeze at all!
Create an async void (for exemple Wait) with Thread.Sleep(x) inside and call it with "await Wait(x) ;" inside an async void.
Avoid
async void
except for async event handlers, plus you can useReadToEndAsync
and make code async all the way through.An example of calling
SetUpTextBox
within the button click event handler, as implied by the comment from original postYou should also put a
try/catch
around everything with the an async void event handler, otherwise any exceptions will go unobserved.Reference Async/Await - Best Practices in Asynchronous Programming
First off, the things you should do, that you aren't:
ReadToEndAsync
.Task.Run
when the task is not CPU bound.async void
when the method is not an event handler.Nkosi has done a decent job illustrating that.
What is left is explaining why
Thread.Sleep(2500)
does not block the UI.First off, notice that
Task.Run
will be running the task using theThreadPool
.You can verify that
System.Threading.Thread.CurrentThread.IsThreadPoolThread
is true inside ofGetText
(for example, you can set a break point and use inspections to check).That means that the UI thread cannot be blocked inside of
GetText
, because the UI thread does not runGetText
.But why then
Thread.Sleep(2500);
yields a different result?Hmmm... what is the difference between:
And:
Let me tell you:
ThreadPool
- that is not it either.-- Sherlock Holmes
The UI is being stuck because you are returning too much text.
Let me put this way...
TOO MUCH TEXT RETURNED
A little text returned:
The UI, is therefore being stuck at
read_Box.Text = textToSet;
, busy trying to render all the text that you got from the file. Or at least that is my hyphothesis.