以下のコードを実行しようとすると、同期操作を実行します。どうして?
次のような警告が出ます…
警告1この非同期メソッドには 'await'演算子がなく、同期的に実行されます。ブロッキングのないAPI呼び出しを待つために 'await'演算子を使用するか、またはバックグラウンドスレッドでCPUバウンドの作業を行うために 'await Task.Run(...)'を使用することを検討してください。
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
「このコードをバックグラウンドスレッドで実行する」という意味ではありません。もっと知りたいのならasync
、 を持っています紹介ブログ記事、MSDNのドキュメント素晴らしいです、そしてありますタスクベースの非同期パターンのフルガイド。
I / Oバウンド(またはイベントベース)操作のシミュレーションをしたい場合は、次のようにします。Task.Delay
の代わりにThread.Sleep
:
public async Task ProcessaA()
{
for (int i = 0; i <= 100; i++)
{
pbProcessoA.Value = i;
await Task.Delay(500);
}
}
あなたがCPUバウンド操作をシミュレートしたいなら、あなたはバックグラウンドタスクにそれらをプッシュオフしているべきです。Task.Run
:
public async Task ProcessaA()
{
for (int i = 0; i <= 100; i++)
{
pbProcessoA.Value = i;
await Task.Run(() => { Thread.Sleep(500); });
}
}
この例を実際の生産システムに書きました。データベースにエンティティを保存すると時間がかかる場合があります。このエレガントなシミュレーションを見てください
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());
}
}