-1

ブローカーからの価格データを処理するプログラムがあります。擬似コードは次のとおりです。

 Process[] process = new Process[50];

 void tickEvent(object sender, EventArgs e)
 {
    int contractNumber = e.contractNumber;

    doPriceProcess(process[contractNumber], e);
 }

マルチスレッドを使用してプログラムを高速化したいのですが、データの契約番号が異なる場合は、別のスレッドを起動してプロセスを高速化したいと考えています。ただし、データが同じコントラクトからのものである場合、次のデータを続行する前に、現在のプロセスが終了するまでプログラムを待機させたいと思います。どうすればいいのですか?

コードを教えてください。

よろしくお願いします〜

4

2 に答える 2

1

ここでは、多くの高レベルのアーキテクチャに関する決定を下す必要があります。

そのブローカーから何ティックが来ると予想しますか?

結局のところ、ここにはある種のディスパッチャが必要です。

基本的に何をすべきかの簡単な説明を次に示します。

  • 着信ティックをパッケージにカプセル化し、必要なすべてのデータを含む最適な単一コマンド

  • これらのコマンドを簡単に (そしてスレッドセーフに) 格納できるキューを用意します。

  • キューのアイテムを取得し、コマンドを実行するワーカーを割り当てる (またはコマンド自体を実行させる) ディスパッチャーを用意します。

  • ワーカーを使用すると、複数のスレッド、プロセス、またはその他のものを使用して、複数のコマンドをシームレスに動作させることができます

  • 時間単位ごとに完了できるようにしたい要求の数に応じて、入力キューに対してすでに何らかのディスパッチを行いたい場合があります。

役立つ情報を次に示します。

C# のコマンド パターン

リアクターパターン(サンプルコード付)

于 2012-07-19T19:56:30.133 に答える
0

Processesの配列を保持するのではなく、 BlockingCollections の配列を保持します。各ブロッキング コレクションは、特定のコントラクトに対応できます。次に、対応するコントラクトのキューの最後に作業を追加するプロデューサー スレッドを作成し、それらのコレクションの結果を消費するプロデューサー キューを作成できます。各スレッド (プロセスではなくスレッドを使用します) が 1-n の異なるキューを処理していることを確認できますが、各キューは 1 つ以下のスレッドによって処理されます。そうすれば、同じコントラクトの作業が並行して処理されないようにすることができます。

Taskこれのスレッド化の側面は、C# のクラスを使用して有効に処理できます。コンシューマについては、それぞれに新しいタスクを作成できますBlockingCollection。そのタスクの本体はほとんど次のようになります。

foreach(SomeType item in blockingCollections[contractNumber].GetConsumingEnumerable())
  processItem(item);

ただし、Tasks を使用すると、コンピュータが適切と判断したときにそれらをスケジュールできます。それらのほとんどが空のキューで待機していることに気付いた場合、使用しているタスク間で回転する実際のスレッドがいくつか (または 1 つだけ) あるだけです。彼らが十分にやろうとしていて、コンピュータが追加のスレッドの負荷を明確にサポートできる場合は、さらにスレッドが追加されます (おそらく、動的に追加/削除されます)。あなたや私よりもはるかに賢い人々にそのスケジューリングを処理させることで、並列化が過小または過大になることなく効率的になる可能性がはるかに高くなります。

于 2012-07-19T19:37:07.520 に答える