5

としてタスクを作成すると

Task task = Task.Factory.StartNew(() => someMethod(args));

C# 4.0 以降では、このタスクのスレッドの参照を取得するにはどうすればよいですか?

タスクを作成した同じスレッドでタスクが実行されるか、複数のスレッドが生成される可能性はありますか?

更新:
理由は次のとおりです。

  • デバッガーでタスクのスレッドを識別したい (およびその名前を属性付けしたい) など。

作成されたタスクは、タスクが作成されたスレッドとは常に別のスレッドで実行されますか?
1 つ、0、または複数のスレッドですか?
単一の同じコアで実行されますか?
たとえば、バックグラウンドワーカーをフリーズさせていると考えてメインスレッドをスリープ状態にすることができるため、知っておくことが重要です。

更新:
役に立つ答え:

4

3 に答える 3

8

作成されたタスクは、タスクが作成されたスレッドとは常に別のスレッドで実行されますか?

いいえ、TPL が、関連するタスク作成オプション (またはタスク スケジューラ) が提供されたために、または最適化として、それを作成したのと同じスレッドでタスクを実行できると判断できる場合があります。それ以外の場合、スレッドは何もしません。ただし、これについて心配する必要はありません。TPL がそのコンテキストでコードを実行することを選択したため、UI スレッドをブロックすることになるわけではありません。特にそうすべきだと示さない限り、それは起こりません。すべての意図と目的のために、これは(強制的に発生させない限り)決して発生しないと想定できますが、舞台裏では、気付かないうちに発生する可能性があります。

1 つ、0、または複数のスレッドですか?

デフォルトでは、タスクはスレッド プールで実行されます。スレッド プールに含まれるスレッドの数は、与えられたワークロードによって異なります。それは 1 つで始まりますが、十分な必要性があれば成長し、その必要性がなくなると縮小します。オプションを指定すると、LongRunningそのためだけに新しいスレッドが作成されTaskます。custom を指定するとTaskScheduler、好きなように実行できます。

単一の同じコアで実行されますか?

可能性はありますが、確実ではありません。

たとえば、バックグラウンドワーカーをフリーズさせていると考えてメインスレッドをスリープ状態にすることができるため、知っておくことが重要です。

メイン スレッドをスリープ状態にしても、バックグラウンド ワーカーの動作は妨げられません。これがバックグラウンド ワーカーを作成する要点であり、2 つのタスクが互いに作業を停止することはありません。バックグラウンド ワーカーが進行状況を報告したり、結果を表示したりするために UI にアクセスしようとしたときに UI がブロックされた場合、その時点で UI スレッドが解放されるのを待機していることに注意してください。

于 2013-03-11T14:36:35.250 に答える
4

次を使用できます。

System.Threading.Thread.CurrentThread

ただし、コメントで述べたように、TPLを使用してスレッドを抽象化するため、この「低レベル」に戻ることは、設計が不十分であることを示している可能性があります。

于 2013-03-11T14:12:11.683 に答える
3

Task.Factory.StartNew() は、実行のためにタスクをキューに入れます (こちらを参照)。タスクを実行する実際のスレッドと、タスクが実行されるタイミングは、指定された TaskScheduler までです (何も指定されていない場合は、現在の TaskScheduler が使用されます)。

.Net 4 では、デフォルトの TaskScheduler は ThreadPool を使用してタスクを実行します (こちらを参照)。そのため、ThreadPool スレッドがタスクをキューに入れている場合、同じスレッドが後でタスクを実行できる可能性があります。

スレッドの数は、ThreadPool によって決定されます。

タスクがどのコアで実行されるかはあまり気にする必要はありません。

実行のためにタスクをキューに入れると、ThreadPool スレッドで実行されるようにスケジュールされる可能性が高いため、誤ってメイン スレッドをスリープ状態にするリスクはありません。

于 2013-03-11T14:40:08.137 に答える