2

セットアップは次のとおりです。FeedDotNetライブラリを使用するフィード リーダーである、比較的単純な Winforms アプリを作成しようとしています。私が持っている質問は、スレッドプールの使用についてです。FeedDotNet は同期 HttpWebRequest を作成しているため、GUI スレッドをブロックしています。そのため、ThreadPool スレッドに同期呼び出しを配置し​​、それが機能している間に、フォームで更新が必要なコントロールを呼び出すのが最善の方法のように思えました。いくつかの大まかなコード:

private void ThreadProc(object state)
{
 Interlocked.Increment(ref updatesPending);

    // check that main form isn't closed/closing so that we don't get an ObjectDisposedException exception
 if (this.IsDisposed || !this.IsHandleCreated) return;
 if (this.InvokeRequired)
  this.Invoke((MethodInvoker)delegate
  {
   if (!marqueeProgressBar.Visible)
    this.marqueeProgressBar.Visible = true;
  });

 ThreadAction t = state as ThreadAction;
 Feed feed = FeedReader.Read(t.XmlUri);

 Interlocked.Decrement(ref updatesPending);

 if (this.IsDisposed || !this.IsHandleCreated) return;
 if (this.InvokeRequired)
  this.Invoke((MethodInvoker)delegate { ProcessFeedResult(feed, t.Action, t.Node); });

 // finished everything, hide progress bar
 if (updatesPending == 0)
 {
  if (this.IsDisposed || !this.IsHandleCreated) return;
  if (this.InvokeRequired)
   this.Invoke((MethodInvoker)delegate { this.marqueeProgressBar.Visible = false; });
 }
}

this= メイン フォーム インスタンス

updatesPending= メインフォームの volatile int

ProcessFeedResult= Feed オブジェクトに対していくつかの操作を行うメソッド。スレッドプール スレッドは結果を返すことができないため、これはメイン スレッドを介して結果を処理する許容可能な方法ですか?

私が最も心配しているのは、これがどのようにスケールするかです。一度に最大 250 件のリクエストを試しました。私が確認したスレッドの最大数は約 53 で、すべてのスレッドが完了すると 21 に戻りました。コードをいじってみた例外的な例の 1 つを思い出すと、120 まで上昇するのを見たことがありました。普通ですよね?また、Windows XP を使用しているため、接続数が非常に多いと、どこかにボトルネックがあると思います。私は正しいですか?

スレッド/接続の最大効率を確保するにはどうすればよいですか?

これらすべての質問があると、これがスレッドプールの使用に適しているかどうかも疑問に思いました。MSDN やその他の情報源は、「短期間の」タスクに使用する必要があると述べています。比較的高速な接続を使用していることを考えると、1 ~ 2 秒の「短命」で十分ですか? ユーザーが 56K のダイヤルアップを使用していて、1 つの要求に 5 ~ 12 秒以上かかる場合はどうなるでしょうか。その場合、スレッドプールも効率的なソリューションになるでしょうか?

4

5 に答える 5

2

The ThreadPool, unchecked is probably a bad idea.

Out of the box you get 250 threads in the threadpool per cpu.

Imagine if in a single burst you flatten out someones net connection and get them banned from getting notifications from a site cause they are suspected to be running a DoS attack.

Instead, when downloading stuff from the net you should build in tons of control. The user should be able to decide how many concurrent requests they make (and how many concurrent requests per domain), ideally you also want to offer controls for the amount of bandwidth.

Though this could be orchestrated with the ThreadPool, having dedicated threads or using something like a bunch of instances of the BackgroundWorker class is a better option.

于 2009-11-17T12:38:36.823 に答える
2

.NET スレッド プールは、新しいスレッドを作成するオーバーヘッドによって新しいスレッドを作成する利点が失われる、実行時間の短いタスクを実行するために特別に設計されています。長時間ブロックしたり、実行時間が長いタスク用には設計されていません。

アイデアは、タスクがスレッドに飛び乗って、すばやく実行し、完了して飛び降りるというものです。

このBackgroundWorkerクラスは、スレッド プール スレッドでタスクを実行する簡単な方法を提供し、タスクが進行状況を報告し、キャンセル要求を処理するメカニズムを提供します。

BackgroundWorker コンポーネントに関するこのMSDNの記事では、このクラスの適切な使用例として、ファイルのダウンロードが明示的に示されています。これにより、このクラスを使用して必要な作業を実行できるようになることを願っています。

スレッド プールの過剰使用が心配な場合は、ランタイムが要求に基づいて使用可能なスレッドの数を管理していることを確認できます。タスクは、実行のためにスレッド プールのキューに入れられます。スレッドが作業を実行できるようになると、タスクがスレッドにロードされます。定期的に、監視プロセスがスレッド プールの状態をチェックします。実行待ちのタスクがある場合は、さらにスレッドを作成できます。アイドル状態のスレッドが複数ある場合は、一部をシャットダウンしてリソースを解放できます。

最悪のシナリオでは、すべてのスレッドがビジーで、作業がキューに入れられている場合、ランタイムは余分なワークロードを処理するためにスレッドを追加します。より多くのスレッドが使用可能になるまで待機する必要があるため、アプリケーションの実行速度は遅くなりますが、実行は続行されます。

于 2009-11-17T12:55:36.680 に答える
2

いくつかのポイントと、情報を組み合わせると、他のいくつかの回答が得られます。

  • ThreadProc には例外処理が含まれていません。それを追加しないと、1 つの I/O エラーでプロセスが停止します。
  • Sam Saffron は、スレッドの数を制限する必要があることはまったく正しいです。(ThreadSafe) Queue を使用してフィードを (WorkItems) にプッシュし、1 つ以上のスレッドでループ内のキューから読み取ることができます。
  • BackgrounWorker は良いアイデアかもしれません。必要な例外処理と同期の両方を提供します。
  • BackgrounWorker は ThreadPool を使用しますが、これで問題ありません。
于 2009-11-17T13:04:06.407 に答える
2

ThreadPool についての私の理解は、このタイプの状況向けに設計されているということです。短命の定義は、この程度の時間であると思います-おそらく数分までです。「存続期間の長い」スレッドは、アプリケーションの存続期間中存続していたスレッドです。

Microsoft は ThreadPool の効率を可能な限り高くするためにいくらかの費用を費やしたことを忘れないでください。もっと効率的なものを書けると思いますか? 私はできなかったことを知っています。

于 2009-11-17T12:33:12.340 に答える
1

「BackgroundWorker」クラスを参照してください。

于 2009-11-17T12:33:05.913 に答える