Reputation: 42642
I expect my GUI will not hang, after reading Asynchronous Programming with Async and Await (C# and Visual Basic)
public async Task<string> DoBusyJob()
{
// Busy Job
Thread.Sleep(10000);
i++;
return "Finished " + i;
}
int i = 0;
private async void button1_Click(object sender, EventArgs e)
{
// Hang!
string result = await DoBusyJob();
this.label1.Text = result;
}
But, it is not. It still hang. I realize I need to add additional await
in DoBusyJob
public async Task<string> DoBusyJob()
{
// Busy Job
await Thread.Sleep(10000);
i++;
return "Finished " + i;
}
int i = 0;
private async void button1_Click(object sender, EventArgs e)
{
// OK!
string result = await DoBusyJob();
this.label1.Text = result;
}
May I know why is it so? Do I really need to have double await
? What if the following case?
public async Task<string> DoBusyJob()
{
// How to prevent Hang?
for (int j = 0; j < 10000000; j++) {
double m = Math.Sqrt(1) + Math.Sqrt(2) + Math.Sqrt(3);
}
i++;
return "Finished " + i;
}
int i = 0;
private async void button1_Click(object sender, EventArgs e)
{
// Hang!
string result = await DoBusyJob();
this.label1.Text = result;
}
Upvotes: 3
Views: 1454
Reputation: 10384
I wish I could understand your // OK!
upon adding await
to Thread.Sleep(10000);
It is impossible to await on method Sleep()
returning void
It is possible to await only on method designating its signature Task
or Task<TResult>
as return type
Async method is executed synchronously without (or until) await
so blocking UI thread
await Task.Run() should return at once to (previous) UI synchronization context, i.e. to continue with next i++; line execution
public async Task<string> DoBusyJob()
{
// Busy Job
await Task.Run(() =>
{
for (int j = 0; j < 10000000; j++)
{
double m = Math.Sqrt(1) + Math.Sqrt(2) + Math.Sqrt(3);
}
}
);
i++;
return "Finished " + i;
}
Upvotes: 0
Reputation: 456322
There's a great answer in the async
/ await
FAQ:
Q. Does using the “async” keyword on a method force all invocations of that method to be asynchronous?
A. No. When you invoke a method marked as “async”, it begins running synchronously on the current thread...
Q. Does the “async” keyword cause the invocation of a method to queue to the ThreadPool? To create a new thread? To launch a rocket ship to Mars?
A. No. No. And no...
You may find my async
/ await
intro helpful.
Upvotes: 2
Reputation: 13161
Please see the excellent answers to this question in regards to async
methods.
Adding async
is insufficient to make the execution of your method asynchronous if you are not using await
with already asynchronous methods. In that case, you need to return a Task
instance that represents the execution of your work, for ex. by calling Task.Factory.StartNew
.
Upvotes: 6