5

スレッド化について学ぶことは間違いなく魅力的であり、それを行うための非常に優れたリソースがいくつかあります。しかし、私の質問は、実際のアプリケーションの設計または開発の一部として明示的に適用されるスレッド化です。

私は C# で広く使用され、よく設計された .NET アプリに取り組んできましたが、明示的な使用の痕跡は見つかりませんでした.これが CLR によって管理されているため、実際の必要性はありませんか、それとも特定の理由がありますか?

また、広く使用されている .NET アプリでコード化されたスレッド化の例。Codelplex や Google Code での参加も大歓迎です。

4

10 に答える 10

5

スレッド化を使用する最も簡単な場所は、UI の応答性を維持しながら、GUI で長い操作を実行することです。

UI スレッドで操作を実行すると、完了するまで GUI 全体がフリーズします。(メッセージ ループを実行しないため)
バックグラウンド スレッドで実行することにより、UI の応答性が維持されます。

BackgroundWorkerクラスはここで非常に便利です。

于 2010-08-05T16:04:58.200 に答える
4

実際のアプリケーションでの設計または開発の一部として明示的に適用されるスレッド化です。

最新のマルチコア システムを最大限に活用するには、最初からスレッディングを設計に組み込む必要があります。スレッド化するコードの小さな部分を見つけるのはかなり簡単ですが (特に .NET 4 では)、実際のスケーラビリティを得るには、できればコードの "高レベル" で、スレッド化を処理するようにアルゴリズムを設計する必要があります。設計段階でこれを行うほど、スレッド化をアプリケーションに適切に組み込むことが容易になります。

これはCLRによって管理されているため、実際には必要ありませんか、それとも特定の理由がありますか?

確かに必要があります。スレッド化は無料ではありません。開発者が追加する必要があります。これが特にオープン ソース コードであまり頻繁に見られない主な理由は、実際にはもっと難しい問題です。.NET 4 を使用しても、スケーラブルで安全な方法でスレッド化するアルゴリズムを適切に設計することは困難です。

于 2010-08-05T16:07:42.560 に答える
3

それは完全にアプリケーションに依存します。

重要な作業を行う必要がある (または、Web サービスの呼び出しなど、他の潜在的に長時間実行されるタスクを実行する)クライアントアプリの場合、バックグラウンド スレッドが使用されることを期待します。BackgroundWorkerこれは、スレッド プールの明示的な使用、Parallel Extensions の明示的な使用、または新しいスレッドの明示的な作成によって実現できます。

私の経験では、Web サービスと Web アプリケーションが独自のスレッドを作成する可能性はやや低くなります。各要求を個別のスレッドとして効果的に処理し (ASP.NET が内部的に移動する場合でも)、すべてを同期的に実行する可能性が高くなります。もちろん、非同期で実行したり、他の理由でスレッドを開始したりする Web アプリケーションもありますが、これはクライアント アプリよりも少ない頻度で発生すると思います。

于 2010-08-05T16:07:09.877 に答える
2

Parallel Extensions to .NET については間違いなく +1 です。Microsoft は、ThreadPool を改善するためにここでいくつかの素晴らしい作業を行いました。以前は、ワーカー スレッドから生成されたものであっても、すべてのタスクを処理する 1 つのグローバル キューがありました。現在、ワーカー スレッドごとにロックフリーのグローバル キューとローカル キューがあります。とてもいい改善です。

Parallel.For、Parallel.Foreach、Parallel.Invoke (リージョン) などはあまり好きではありません。クラス ライブラリではなく、純粋な言語拡張であるべきだと考えているからです。明らかに、この中間ステップがある理由は理解していますが、C# が同時実行性のために言語を改善することは避けられず、それを利用するためにコードを変更して元に戻さなければならないことも同様に避けられません :-)

全体として、.NET で並行アプリを構築することを検討している場合は、Parallel Extensions について詳しく調べる必要があります。また、これはマイクロソフトのかなり初期の取り組みであることを考えると、自分のスキルレベルが並行性であると認識しているかどうかに関係なく、何がうまくいき、何がうまくいかないかについて非常に声に出す必要があると思います. Microsoft は確かに耳を傾けていますが、Parallel Extensions をまだ使用している人はそれほど多くないと思います。私は昨日 VSLive レドモンドにいて、このトピックに関するセッションを見て、これに取り組んでいるチームに感銘を受け続けています.

開示: 以前は Visual Studio のマーケティング ディレクターでしたが、現在はCorensicというスタートアップに所属しており、並行アプリのバグを検出するツールを構築しています。

于 2010-08-05T17:29:40.773 に答える
1

私が見たスレッドの実際の使用法のほとんどは、UI、ネットワーク、データベース呼び出しなどのブロックを単純に回避することです。

メソッドのペア、呼び出し、呼び出しとして使用さBeginXXXれているのを見るかもしれません。EndXXXdelegate.BeginInvokeControl.Invoke

私が見たいくつかのシステムでは、スレッディングが恩恵をもたらしますが、実際には分離の原則を使用して複数の「スレッド」を実現しています。スレッディング」(またはメニーコアの利用)は、すべてのプロセスを一度に実行するだけで自動的に達成されます。

多くの株式取引アプリケーション (データ表示) は大規模な並列化をほとんど必要とせず、それに適した設計が常に可能であるとは言えないと言っても過言ではありません。私が見た例はすべて非常に具体的な問題です。これは、目立った実装が見られなかった理由に起因する可能性があります。

于 2010-08-05T16:07:43.123 に答える
1

明示的なスレッド実装を使用するかどうかの問題は、他の人がここで述べたように、通常は設計上の考慮事項です。後付けとして並行性を実装しようとすると、通常、多くの抜本的で大規模な変更が必要になります。

各スレッドの管理にコストがかかり、メモリのオーバーヘッドもあるかもしれないことを考えると、単純にスレッドをアプリケーションに投入しても、本質的にパフォーマンスや速度が向上するわけではないことに注意してください (もちろん、デバッグは楽しいものです)。

私の経験からすると、スレッド化設計を実装する最も一般的な場所は、Windows サービス (バックグラウンド アプリケーション) と、大量の作業をより小さな作業区画に簡単に分割 (およびハンドオフ) できるユース ケース シナリオを持つアプリケーションでした。非同期に完了するスレッドへ)。

例として、 Microsoft Robotics Studioをチェックアウトできます(私が知る限り、今は無料バージョンがあります) - Concurrency and Coordination Runtimeの再配布可能 (スタンドアロンのダウンロードとしては見つかりません) が付属しています。 Microsoft のChannel 9で一部報道されました。

他の人が言及したように、Parallel Extensions チーム (ブログはこちら) は、スレッド セーフと並列実行に関して優れた作業を行っており、 MSDN Code サイトでいくつかのサンプル/例を見つけることができます。

于 2010-08-05T17:51:56.260 に答える
0

スレッド化はあらゆる種類のシナリオで使用されます。明示的 (ソケット関連) であろうと暗黙的 (Web サービス) であろうと、ネットワーク ベースのものはすべてスレッド化に依存します。スレッド化により、UI の応答性が維持されます。また、複数の並列実行を持つ Windows サービスは、処理する必要があるキューを介してデータを処理する際に同じことを行います。

これらは私が見た最も一般的なものです。

于 2010-08-05T16:10:00.140 に答える
0

ほとんどの回答は、GUI アプリケーションで実行時間の長いタスクを参照しています。私の経験では、もう 1 つの非常に一般的な使用シナリオは、プロデューサー/コンシューマー キューです。多数のエンドポイントに対して頻繁に Web リクエストなどを実行する必要がある多くのユーティリティ アプリケーションがあります。プロデューサー/コンシューマー スレッド パターンを (通常はカスタム スレッド プールを統合することによって) 使用して、これらのタスクの高度な並列化を可能にします。

実際、まさに今、200MB のファイルを 200 の異なる FTP ロケーションにアップロードするアプリケーションを調べています。私たちはSmartThreadPoolを使用し、最大約 50 のアップロードを並行して実行します。これにより、バッチ全体が 1 時間以内に完了します (すべてのアップロードが連続して行われた場合は 50 時間以上かかるのに対し、私たちの使用法では、ほぼ直線的な改善が見られます)。時間)。

于 2010-08-05T16:14:13.060 に答える
0

現代のプログラマーは抽象化が大好きなので、Async メソッドまたは BeginInvoke を呼び出してスレッドを使用し、.Net 4 で BackgroundWorker や PFX などを使用します。

それでも、スレッド化を自分で行う必要がある場合があります。たとえば、私が構築した Web アプリには、アプリ内から追加するメール キューがあり、メールを送信するバックグラウンド スレッドがあります。スレッドは、送信しているよりも速くキューがいっぱいになっていることに気付いた場合、別のスレッドを作成し、そのスレッドがアイドル状態であることを確認すると、そのスレッドを強制終了します。これは、私が推測するより高いレベルの抽象化で行うことができますが、手動で行いました。

于 2010-08-05T16:21:28.857 に答える
0

高度な運用の確実性を達成する必要があるか、高度の運用上の不確実性を許容する必要がある一部のアプリケーションでは、最初のアーキテクチャ設計から最終的な配信までスレッドとプロセスが考慮されます。

ケース 1 - 非常に高いレベルの運用上の信頼性を達成する必要があるシステムの場合、投票アーキテクチャで 3 つの異なるメカニズムを使用する 3 つの完全に独立したサブシステムを使用できます - 各ボーター間で 3 つのスレッド/プロセスを生成し、それらが終了/終了/終了するのを待ちます殺され、進む IFF 彼らは皆同じ​​ことを言う - 例 - 複雑なアビオニックシステム

ケース 2 - 高度な操作の不確実性に対処しなければならないシステムの場合 - 同じことを行いますが、何か/何かが戻ってきたら、ストラグラーを殺し、得られた最良の答えを出します - 例 - 複雑な日中取引それらを使用するビジネスを破壊しようとするアルゴリズム:-)

于 2010-08-05T19:21:46.230 に答える