UIベースではないアプリケーション(ASP.NET)とUIベースのアプリケーション(WinFormとWPF)の両方について、次のようなライブラリがあるとします。残念ながらIOバインド作業とCPUバインド作業を混同することは避けられませんが、Task.Run
経由でDummyWorkAsync
を呼び出すか、アプリケーションタイプ(非UIベースまたはUIベースのアプリケーション)に基づいて消費者に呼び出させます。通常のラムダと非同期のラムダとの間に違いはありますか?
class DummyService
{
public static async Task<int> DummyWorkAsync()
{
// Do some I/O first.
await Task.Delay(1000);
// Tons of work to do in here!
for (int i = 0; i != 10000000; ++i)
;
// Possibly some more I/O here.
await Task.Delay(1000);
// More work.
for (int i = 0; i != 10000000; ++i)
;
return 0;
}
}
これは、UIベースの消費者が適切に次のようにASP.NETクライアントはちょうど直接メソッドを呼び出すだろうが、サービスを呼び出すためにTask.Run
を使用することができます。
private async void MyButton_Click(object sender, EventArgs e)
{
await Task.Run(() => DummyService.DummyWorkAsync());
}
public class Home: Controller
{
public async Task<ActionResult> IndexAsync()
{
var result = await DummyService.DummyWorkAsync();
return View(result);
}
}
質問
私はUIベースのアプリケーションに興味があります。私は
private async void MyButton_Click(object sender, EventArgs e)
{
await Task.Run(async() => await DummyService.DummyWorkAsync());
}
ではなく
private async void MyButton_Click(object sender, EventArgs e)
{
await Task.Run(() => DummyService.DummyWorkAsync());
}
を使用している場合は任意の違いはありますか?
:最初は残りの(重いCPUの仕事を)待った後、あなたが最初の場所で
Task.Run
を使用する必要はありません(少なくともデフォルトのスケジューラを持つ)、ので、その場合には、スレッドプールのスレッド上で実行されます最初のものは、 'DummyWorkAsync'がUIスレッドで終了した後に何かをする必要がある場合にのみ役に立ちます。つまり、実際には終了するのを実際に待っていますが、UIスレッドをブロックしません。 – juharr@Clemens:「ハイブリッド」の「DummyWorkAsync」にCPUバインドされた作品がいくつか存在するためです。このようなハイブリッド非同期メソッドには、UIベースのアプリケーションで 'Task.Run'を使う必要があります。 –
あなたのIOが最初に行くから(私は最初にTask.Delayを待っています)なぜそれにConfigureAwait(false)を追加しないのですか?その後、Task.RunをラップすることなくUIから呼び出すことができます。 – Evk