最後の1つがトレッド管理を抽象化する場合、BackgroundWorkerよりもSystem.Threadingを直接使用することを選択するのはなぜですか?
System.Threadingの代わりにBackgroundWorkerを使用できなかったケースが表示されません。
最後の1つがトレッド管理を抽象化する場合、BackgroundWorkerよりもSystem.Threadingを直接使用することを選択するのはなぜですか?
System.Threadingの代わりにBackgroundWorkerを使用できなかったケースが表示されません。
BackgroundWorker
.NET 2.0から存在しており、バックグラウンドスレッドで実行され、UIスレッドを停止させないコードの記述を支援することを目的としています。もともとはWindowsフォームで登場しましたが、同期コンテキストを登録するWPFまたは将来のUIフレームワークでも機能します。InvokeRequired
これにより、キャンセルを処理したりBeginInvoke
、サポートしたりすることなく、進行状況と結果をUIスレッドに報告できます。
タスク並列ライブラリ(TPL)は.NET 4で導入され、非同期タスクをモデル化することを目的としています。これらのタスクは非同期であり、別のスレッドで実行される場合と実行されない場合があります。別のスレッドで実行されないものの例としては、非同期IOや、UIで実行する必要のあるタスクがあります(非同期のままです)。このタスクメタファーは、future(または継続)もサポートしているため、ContinueWith
特定の同期コンテキストを使用してタスクをチェーンし、UIスレッドでタスクを実行するなどの操作を実行できます(たとえば、UIを更新するため)。
タスクはキャンセルもサポートしており、複数のタスクがキャンセルトークンを共有できるため、要求されたキャンセルによって複数のタスクがキャンセルされます。
違いの1つは、Task
進行状況をUIに報告する固有の方法がないことです。もちろん可能ですが、インターフェースには組み込まれていません。 Task
■キャンセルもサポートしています。
バックグラウンドで実行したいことが1つだけあり、レポートの進行状況などのUIに具体的に連絡したい場合は、をお勧めしBackgroundWorker
ます。それ以外の場合は、通常、使用することをお勧めしますTask<T>
(またはTask
結果が不要な場合)。 Task
本質的にC#5 async/await構文で使用されます...
それぞれのアプローチの意図を考えてみてください。
BackgroundWorkerは、主に最初からWindowsフォーム用に設計されており(WPFでも使用できます)、非同期操作の一部の機能のみを提供します。System.Threadingのすべてのクラスと比較すると、BackgroundWorkerが明らかにそれらに基づいて構築されていることがわかります。
System.Threadingの下にあるすべてのクラスを使用して、独自のBackgroundWorkerを構築し、より多くの機能を楽しんだり、コードを制御したりできます。ここでの難しさは、鋭い学習曲線とデバッグの課題です。
したがって、BackgroundWorkerで十分だと思われる場合は、引き続き使用してください。足りないものを見つけた場合は、System.Threadingのビルディングブロックが役立ちます。
.NET Framework 4では、MicrosoftはSystem.Threadingに基づいて、タスクベースの非同期パターンという名前の別のクラスのセットを設計します。
http://www.microsoft.com/en-us/download/details.aspx?id=19957
これを使用すると、BackgroundWorkerのことをほとんど忘れることができます。これは、System.Threadingを直接操作する複雑さに飛び込む必要がなく、はるかに多くの機能を提供し、十分な制御を提供するためです。
I have a blog post on the subject.
In short, you should use async Task
s if you possibly can. Thread
does provide some additional "knobs" - such as Priority
- but usually those knobs are not necessary, and programmers often turn them the wrong way anyway.
1つは、BackgroundWorkerでスケジューリングの優先順位を設定することはできませんが、スレッドでは設定できます。
私の答えに疑問を呈するコメントは、引き続きTaskとThreadPoolを参照しています。述べられている質問は、タスクやスレッドプールに関するものではなく、私の答えでもありません。
上記のリンクからのコードサンプルを参照してください。スレッドを開始する前に優先順位を割り当て、スレッドの開始を制御することを明確に示しています。
完全なコードサンプル:
PriorityTest priorityTest = new PriorityTest();
ThreadStart startDelegate = new ThreadStart(priorityTest.ThreadMethod);
Thread threadOne = new Thread(startDelegate);
threadOne.Name = "ThreadOne";
Thread threadTwo = new Thread(startDelegate);
threadTwo.Name = "ThreadTwo";
threadTwo.Priority = ThreadPriority.BelowNormal;
threadOne.Start();
threadTwo.Start();
// Allow counting for 10 seconds.
Thread.Sleep(10000);
priorityTest.LoopSwitch = false;
私はこれをテストし、ThreadTwoはThreadPriority.BelowNormalで開始および終了します。私のテストでは、threadOneはthreadTwoとして約10倍を処理します。
BackGroundWorkerにはPriorityプロパティはありません。BackgroundWorkerは、デフォルトの優先度であるNormalで開始します。BackgroundWorkerスレッドの優先度はDoWorkで変更できますが、作業の開始後にスレッドの優先度を変更することは明らかに同じではありません。