1

ハードウェア デバイスから一連の値を 50 ミリ秒ごとに名前と値のペアの形式で受け取るコードを開発しました。特定のアイテムの値が変更されたときにサブスクライバーに通知できるパブ/サブ サービスを開発したいと考えています。Subscribe メソッドは次のようになります。

public void Subscribe(string itemName, Action<string, long> callback)

ハードウェア値を読み取るコードは、値が前回から変更されたかどうかを確認します。その場合、そのアイテムのサブスクライバーを繰り返し処理し、デリゲートを呼び出します。現状では、デリゲートは同じスレッドで呼び出されますが、これは理想的ではありません。ポーリングをできるだけ高速に保つ必要があります。別のスレッドでコールバック デリゲートを呼び出すための最良の方法は何ですか? サブスクライバーは (たとえば) タスク/スレッドを渡す必要がありますか、それともパブリッシャーがこれらのスピンアップを担当する必要がありますか?

いくつかのパラメーター (アイテム名とその値) をデリゲートに渡す必要があることに注意してください。これは、採用するアプローチに影響を与える可能性があります。単一の「状態」オブジェクトをタスクに渡すことができることは知っていますが、サブスクライバーにアクション コールバック デリゲートを実装するよう要求するのは少し直感的ではないように感じます (その後、名前と値を含む他の型にキャストする必要があります)。

また、デリゲートが呼び出されるたびに新しいタスク/スレッドを作成するとパフォーマンスが低下すると想定しているため、何らかの「プール」が必要になる可能性がありますか?

4

1 に答える 1

1

私はあなたが今持っているのと同じ構造を維持し、迅速な行動の責任をコールバックに置きます。コールバックは、複雑で時間のかかるアクションを直接ブロックしたり、実行したりしてはなりません。

特定のコールバックが時間のかかるアクションを実行する必要がある場合は、アクション データを独自のスレッドのキューに入れ、「すぐに」返す必要があります。GUIスレッドにデータをBeginInvoke/PostMessageするか、DBテーブルに挿入するスレッドにキューに入れるか、ロガーにキューに入れるか(実際には、一緒にチェーンされた任意のコンボ)。これらの時間のかかる/ブロックするアクションは、デバイス インターフェイスがポーリングを続けている間、並行して続行できます。

このようにして、現在の作業構造を維持し、それを必要としないコールバックにスレッド間通信を課す必要がなくなります。デバイス インターフェイスはカプセル化されたままで、コールバックを起動するだけです。

編集:

「デリゲートが呼び出されるたびに新しいタスク/スレッドを作成すると、パフォーマンスが低下します」-はい、状態を維持することも困難です。多くの場合、そのようなスレッドは while(true) ループとして記述され、上部に何らかのシグナル呼び出しがあります。ブロッキング キュー pop() であるため、作成する必要があるのは起動時に 1 回だけで、終了する必要はありません。

于 2012-08-16T09:55:54.447 に答える