3

c#5.0の新しい非同期言語機能は、Taskオブジェクトに大きく依存しており、多くの例は、タスクでコードの一部を実行する一般的な方法の1つが、コードをTask.Run()を介して開始することであることを示しています。タスクを実行し、スレッドプールスレッドで実行します。

ただし、スレッドプールスレッドで長時間実行されるコードを開始するべきではないことも読みました。これにより、この質問が発生します。すべてのC#非同期言語機能(Task、'await'、'asyncなど)を引き続き使用できますか? ')「通常の」スレッドでスレッドプールを使用しませんか?この場合、「通常の」スレッドで実行されているコードを表すTaskオブジェクトをどのように取得しますか?

そして、スレッドプールで長時間実行されるコードを実行しないというルールについてのフォローアップの質問として、このルールはCPUを集中的に使用するコードについてのみですか?コードが長時間(たとえば72時間)実行されても、ほとんどの時間を「await Task.Delay()」などの処理に費やしている場合はどうなりますか。スレッドプールスレッドを使用しても問題ありません。または、「通常」を使用する必要があります。並行コードを長時間実行する必要があるすべての場合のスレッド?

4

2 に答える 2

3

Taskカスタムを作成することで、どこでもsを実行できますTaskScheduler

ただし、実行しているのがawait Task.Delay()、である場合は、気にしないでください。
非同期呼び出しの全体的な目的は、何かが起こるのを待っている間、スレッドを保持しないことです。待っている間Task.Delay()、実行中のスレッドはまったくありません。

実際に同期コードを長時間実行している場合は、TaskCreationOptions.LongRunning強制的に新しいスレッドを作成するように指定できます。

于 2012-11-08T22:58:41.743 に答える
3

また、スレッドプールスレッドで長時間実行されるコードを開始するべきではないことも読みました。

スレッドプール長時間実行されるコードに正しく応答するため、それができないわけではありません。これは、最も効率的な方法ではありません。

また、これは「長時間実行」の反対Task.Delayを意味することに注意してください。個人は実際にはその時点で完了し、スレッドプールには存在しなくなります。もう1つが作成され、完了するとスレッドプールにキューに入れられます。(デリゲートを渡すと)返されるのは、実際にはデリゲート全体を表す「プロキシ」です。TaskawaitTaskTask.DelayTaskTask.RunasyncTask

「通常の」スレッドですべてのC#非同期言語機能(Task、'await'、'async'など)を使用し、スレッドプールを使用しないことは可能ですか?

あなたの状況では、それは必要ありませんが、それ可能です。私のAsyncExライブラリには、そのスレッドでsを開始するために使用できるプロパティをAsyncContextThread公開するタイプが含まれています。TaskFactoryTask

Task.Run()を使用してすべてのインスタンスを「並行して」サービスしています

あなたの場合、あなたは必要がないTask.Runか、まったく必要ありませんTaskFactory。スレッドプールに作業を明示的に送信しなくても、これを並行して簡単に実行できます。

string[] instanceNames = ...;
var tasks = instanceNames.Select(ServiceInstanceAsync);
await Task.WhenAll(tasks);

private static async Task ServiceInstanceAsync(string name)
{
  await DownloadAndProcessFileAsync();
  await Task.Delay(15000);
  await ExecuteSSHAsync();
}
于 2012-11-09T00:10:16.293 に答える