I'm fairly new to async/await programming and sometimes I feel that I understand it, and then all of a sudden something happens and throws me for a loop.
I'm trying this out in a test winforms app and here is one version of a snippet that I have. Doing it this way will block the UI
private async void button1_Click(object sender, EventArgs e)
{
int d = await DoStuffAsync(c);
Console.WriteLine(d);
}
private async Task<int> DoStuffAsync(CancellationTokenSource c)
{
int ret = 0;
// I wanted to simulator a long running process this way
// instead of doing Task.Delay
for (int i = 0; i < 500000000; i++)
{
ret += i;
if (i % 100000 == 0)
Console.WriteLine(i);
if (c.IsCancellationRequested)
{
return ret;
}
}
return ret;
}
Now, when I make a slight change by wrapping the body of "DoStuffAsync()" in a Task.Run it works perfectly fine
private async Task<int> DoStuffAsync(CancellationTokenSource c)
{
var t = await Task.Run<int>(() =>
{
int ret = 0;
for (int i = 0; i < 500000000; i++)
{
ret += i;
if (i % 100000 == 0)
Console.WriteLine(i);
if (c.IsCancellationRequested)
{
return ret;
}
}
return ret;
});
return t;
}
With all that said, what is the proper way to handle this scenario?
When you write such code:
private async Task<int> DoStuffAsync()
{
return 0;
}
This way you are doing things synchronously, because you are not using await
expression.
Pay attention to the warning:
This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
Based on the warning suggestion you can correct it this way:
private async Task<int> DoStuffAsync()
{
return await Task.Run<int>(() =>
{
return 0;
});
}
To learn more about async/await you can take a look at:
You just need to change the DoStuffAsync task little bit, as below.
private async Task<int> DoStuffAsync(CancellationTokenSource c)
{
return Task<int>.Run(()=> {
int ret = 0;
// I wanted to simulator a long running process this way
// instead of doing Task.Delay
for (int i = 0; i < 500000000; i++)
{
ret += i;
if (i % 100000 == 0)
Console.WriteLine(i);
if (c.IsCancellationRequested)
{
return ret;
}
}
return ret;
});
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.