When I try to run the code below, perform synchronous operations. Why?
I get the following warning ...
Warning 1 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.
private async void btProcessa_Click(object sender, EventArgs e)
{
await ProcessaA();
await ProcessaB();
}
public async Task ProcessaA()
{
for (int i = 0; i <= 100; i++)
{
pbProcessoA.Value = i;
Thread.Sleep(500);
}
}
public async Task ProcessaB()
{
for (int i = 0; i <= 100; i++)
{
pbProcessoB.Value = i;
Thread.Sleep(500);
}
}
async
does not mean "run this code on a background thread". If you want to know more about async
, I have an introductory blog post, the MSDN docs are great, and there's a full guide to the Task-based Asynchronous Pattern.
If you want to do some simulation of I/O-bound (or event-based) operations, you should use Task.Delay
instead of Thread.Sleep
:
public async Task ProcessaA()
{
for (int i = 0; i <= 100; i++)
{
pbProcessoA.Value = i;
await Task.Delay(500);
}
}
If you want to simulate CPU-bound operations, then you should be pushing them off to a background task via Task.Run
:
public async Task ProcessaA()
{
for (int i = 0; i <= 100; i++)
{
pbProcessoA.Value = i;
await Task.Run(() => { Thread.Sleep(500); });
}
}
I wrote this example to a real production system. Save the entities in a database can take time. Look at this elegant simulation
class TestAsyncAwait
{
public void GetEntities()
{
for (int i = 0; i < 4; i++)
{
var a = getEntities(i);
saveEntitiesAsync(a);
}
Console.WriteLine("\nPress any key to close\n");
Console.ReadKey();
}
private List<string> getEntities(int i)
{
Console.Write("getting Entities for id={0}...", i);
Thread.Sleep(2000);
var r = new List<string> { i.ToString(), " Hello!" };
Console.WriteLine("done, has the Entities for id={0}\n", i);
return r;
}
async void saveEntitiesAsync(List<string> a)
{
var sb = new StringBuilder();
await Task.Run(() =>
{
Thread.Sleep(4000); // simulates long task
foreach (string s in a) sb.Append(s);
});
// shows the thread in action
Trace.WriteLine("saved: " + sb.ToString());
}
}