2009-11-21 18 views
54

.NET 4.0で見たことのある人もいますが、新しい名前空間System.Threading.Tasksを追加しました。これは基本的に意味、タスクです。私は数日間、ThreadPoolの使用からそれを使用してきました。C# - ThreadPoolとタスク

どちらが効率的で、リソース消費量は少ないですか?

+8

私はタスクがThreadPoolを利用していると思います。 – leppie

答えて

21

タスクの名前空間の目的は、マルチタスクアプリケーションの作成を容易にし、柔軟性を高めるためのプラガブルアーキテクチャを提供することです。

実装では、TaskSchedulerオブジェクトを使用してタスクの処理を制御します。これには、独自のタスク処理を作成するためにオーバーライドできる仮想メソッドがあります。メソッドは、.NETスレッド実装のラッパーがありますように、デフォルトの実装を使用する小さなオーバーヘッドがありますインスタンス

protected virtual void QueueTask(Task task) 
public virtual int MaximumConcurrencyLevel 

のために含まれ、私はそれが巨大であることを期待していないと思います。

単一のスレッドhereに複数のタスクを実装するカスタムTaskSchedulerの(ドラフト)実装があります。

+8

非常に真実ですが、私はTaskクラスの主な目的や魅力がカスタムスケジューラだとは思いません。これは非常に特殊な機能で、場合によっては非常に重要ですが、ほとんどのユーザーは決してそれに触れません。 –

19

どれが効率的で、リソース消費量が少なくて済みますか。 リソースを消費しますか?

無関係に、ほとんど違いはありません。それが起動し、スレッドへの参加、および転送の例外のための非常にクリーンなインターフェイスを提供していますよう

(それとも、より全体的な)

Taskクラスは使いやすいだろう。また、負荷分散の(制限された)形式をサポートしています。

+4

タスクは、.NETでParallelフレームワークを使用するより簡単な方法です。スレッドはOSから直接取得され、直ちに実行され、より多くのCPU時間を消費し、一般にフレームワークがコンテキスト切り替えと最適化技術を管理することを許可しません。これはTANTRUMを投げて、私が今すぐ欲しいと叫んだ子供に似ています!彼らのターンを待っている誰か? –

+0

@MickeyPerlstein。スレッドの使用についてのあなたの記述は、OPが要求しているスレッドプール(クラスThreadPool)には実際には適用できません。タスクは、特に高度なシナリオでは、複数のCPUを利用するより効果的な方法ですが、単純な状況では、 'ThreadPool.QueueUserWorkItem'は完全に適切と思われます。コメント? – ToolmakerSteve

+0

@ToolmakerSteveは1つのシステムを使い、よく学びます。タスクは、msが推奨するものです。 QueueUserWorkItemはあまりにも多くの癖を持っています。なぜなら、彼らが最初にタスクを発明した理由です。それは "約束"のパラダイム –

4

ThreadPoolを使用すると、実行中のスレッドを中断または待機させる方法はありません(スレッドの方法で手動で行う場合を除き)。タスクを使用しています可能です。私が間違っていると私を修正してください。

+2

AFAIKあなたはタスクを中止することはできません、あなたはそれを試してキャンセルすることができますが、私の経験では常に動作しない...スレッドとして。例えば、Abort()は、常に動作します:) – argh

+4

実際にはcancelationtokenを使用してスレッドプールとタスクの両方をキャンセルできます。 C#経由でclrを参照してください。 – DarthVader

5

スケジューリングは並列タスクの重要な側面です。

スレッドとは異なり、新しいタスクは必ずしもすぐに実行を開始するとは限りません。代わりに、作業キューに配置されます。タスクは、関連するタスクスケジューラがキューからそれらを削除するときに実行されます。通常、コアが使用可能になると、タスクが実行されます。タスクスケジューラは、システムの並行性を制御することによって、全体のスループットを最適化しようとします。十分なタスクがあり、タスクが依存関係を十分にシリアライズしていない限り、プログラムのパフォーマンスは使用可能なコアの数に比例します。私は、MSDN http://msdn.microsoft.com/en-us/library/ff963549.aspx

+0

ThreaPoolと同じですから、どのように違うのですか? – sam

+1

良い点、私はちょうどもっと構文的な砂糖を推測する。 –

14

で見たように、このように、タスクは、潜在的な並列処理

のコンセプトを具現化「の.NET Framework 4以降では、TPLは、マルチスレッドと並列コードを書くための好ましい方法です。「

http://msdn.microsoft.com/en-us/library/dd460717.aspx

0

スレッド

ベアメタル事は、あなたはおそらく、あなたはおそらく、その施設からLongRunningタスクと利益を使用することができ、それを使用する必要はありません。

タスク

スレッドよりも抽象的なはスレッドプールを使用します(タスクをLongRunning操作として指定しないかぎり、新しいスレッドはあなたのためにフードの下に作成されます)。

スレッドプール

名前が示すとおり、スレッドのプール。 .NET Frameworkは、限られた数のスレッドを処理しますか?どうして? 8コアだけでCPU上で高価なCPU操作を実行するために100スレッドを開くことは間違いありません。フレームワークはこのプールを維持し、スレッドを再利用します(各操作でそれらを作成/削除せずに)、CPUが焼き付けられないようにいくつかを並列に実行します。

でも、どちらを使うのですか?

再開時:常にタスクを使用します。

タスクは抽象的なものなので、使用するのがはるかに簡単です。私はあなたが常にタスクを使用しようとすることをお勧めします。スレッドを自分で処理する必要がある(おそらく1%の時間)スレッドを使用する必要があるいくつかの問題に直面した場合は、

しかし、それに注意してください。

  • I/Oバウンド:I/Oバウンドの操作(データベース呼び出しは、/書き込みファイル、APIの呼び出しなどを読んで)については、通常のタスク、使用を使用することはありませんLongRunningタスクやスレッドが必要ですが、通常のタスクは必要ありません。いくつかのスレッドがビジー状態のスレッドプールにつながり、プールを取るために待っている別のタスクがたくさんあるためです。
  • CPUバインド:CPUバインド操作の場合は、通常のタスクを使用して満足してください。
+0

I/Oのタスクを回避するためのアドバイスは間違っています。タスクはI/Oバウンド操作のために完全に機能し、 'async'と' await'によって奨励されます。 –

+0

関連するトピックでさえ、 'async'と' await'はここでは議論されませんでした。しかし、とにかく、彼らはI/O操作のために "ThreadPool Threads"(通常のタスク)を実装していません。 @StephenClearyからの答えを[this](https://stackoverflow.com/a/14902702/890890)で見ることをお勧めします。彼の両方の例では、 'Task.Run()'を使用しません(これは、別のコンテキストで実行されているスレッドプールスレッドを生成します)。他の答えも非常に有用です。 – fabriciorissetto

関連する問題