Reputation: 11117
So I'm learning about async/await in C#, I made a small Windows forms app to just play with async/await. I came up with these:
Here is the button1_Click
that's used for the two methods below:
private void button1_Click(object sender, EventArgs e)
{
GetSiteAsync();
}
and here is the look of the app:
Method 1:
public async void GetSiteAsync()
{
HttpClient ht = new HttpClient();
Task<string> getTaskString = ht.GetStringAsync("http://stackoverflow.com");
label1.Text = "Loading...";
string siteString = await getTaskString;
label1.Text = "Finished! Site Length = " + siteString.Length;
}
Method 2:
public async void GetSiteAsync()
{
HttpClient ht = new HttpClient();
string siteString = await ht.GetStringAsync("http://stackoverflow.com");
label1.Text = "Loading...";
label1.Text = "Finished! Site Length = " + siteString.Length;
}
In the first method when i click on 'Load URL' button, it changes the label to 'Waiting...' and when loading is finished it changes it to 'Finished!' with the site length appended to it.
In the second method when I click on the button it doesn't change the label and when operation is completed it changes the label to the site length.
I noticed that both methods don't cause the program GUI to freez while loading the website.
So Why does second method fail to change the button to 'Loading...'??
Upvotes: 2
Views: 82
Reputation: 203819
In the first method you set the label test to loading and then await
the task.
In the second method you await
the task (meaning you don't continue executing the rest of the code in the method until it's already done) and then you set the label to loading (and then set it to done immediately afterward).
The methods don't block the UI thread because they're asynchronous; they return control to the calling code very quickly, and continue to do work after yielding control.
Upvotes: 1
Reputation: 53958
The code after an await
operator is executed after the call in the await
have been completed. This may be done in another thread. In the background a state machine is created and we say that the code after the await
would be executed in a continuation.
So in the first case,
Task<string> getTaskString = ht.GetStringAsync("http://stackoverflow.com");
label1.Text = "Loading...";
You just make an asynchronous call and then you set the Text
value of the label1
.
While in the second case,
string siteString = await ht.GetStringAsync("http://stackoverflow.com");
label1.Text = "Loading...";
you await
this call. This means that after the completion of this asynchrnous call, the setter of the label1.Text
would be executed.
Upvotes: 3
Reputation: 2060
The second method immediately jumps to the label1.Text = "Finished! Site Length = " + siteString.Length;
line after the label1.Text = "Loading...";
line, so you never actually see it. The first method, you see it, because the await happens after.
So: First method: "loading" -> await -> "Finished!" Second method: await -> "loading" -> "Finished!"
The "loading" is immediately written over in the second method.
Upvotes: 2