2

同時に実行され、データを共有する2つの異なるアプリケーションの統合に取り組んでいます。1つのアプリケーションはデータを提供し、もう1つのアプリケーションは外部システムとデータに基づいていくつかの値を計算し、それを最初のアプリケーションに提供する必要があります。

このライブラリを使用して、アプリケーション間でデータを共有しています:http: //grouplab.cpsc.ucalgary.ca/cookbook/index.php/Toolkits/Networking

ライブラリは基本的に、任意のアプリケーションからクエリできる共有ディクショナリを作成できます(共有ディクショナリの場所を知っている限り)。

したがって、プログラムAはプログラムBにデータを提供する必要があり、プログラムBはこのデータを使用して、他のデータをプログラムAに返します。

私の問題は、プログラムAにBからの応答を待機させる方法です。より具体的には、オブジェクトを共有ディクショナリに配置し、他のプログラムにディクショナリの変更が通知され、いくつかの属性を計算できます。ディクショナリ内のオブジェクトを更新します。プログラムAは通知を受け取ることができますが、プログラムAがこの応答を返すまで待機する必要があります。プログラムAのアクションは、戻り値に基づいている必要があります。

これを実行できる非常に醜い方法は、関数内に無限ループを設定することです。これにより、辞書にクエリを実行して、オブジェクトが更新されているかどうかを確認します。ループから抜け出し、オブジェクトとその計算された属性を使用している場合。誰かがより良い解決策を知っていますか?

4

4 に答える 4

2

それらのサブスクリプションモデルを使用すると、すべての無限ループを回避できます。 何かが実際に更新されたときだけチェックする必要があるのに、なぜループする必要があるのでしょうか。 辞書でキーパターンをサブスクライブすると、そのパターンに適合するキーが更新/追加されたときに接続が通知されるため、確認するだけで済みます。

したがって、基本的には、ManualResetEventを使用して、独自のシステム内で同期を待機できます。ManualResetEventの使用例を次に示します。

using System;
using System.Threading;

class Program
{
    static void Main(string[] args)
    {
        //    create the reset event -- initially unsignalled
        var resetEvent = new ManualResetEvent(false);
        //    information will be filled by another thread
        string information = null;

        //    the other thread to run
        Action infoGet = delegate
        {
            //    get the information
            information = Console.ReadLine();
            //    signal the event because we're done
            resetEvent.Set();
        };

        //    call the action in a seperate thread
        infoGet.BeginInvoke(null, null);
        //    wait for completion
        resetEvent.WaitOne();
        //    write out the information
        Console.WriteLine(information);
    }
}

フレームワークに変換するには、サブスクリプションハンドラーに更新内容を確認させ、その待機ハンドルを見つけてシグナルを送信し、適切な待機スレッドを進めます。

于 2010-01-21T06:47:23.010 に答える
1

ManualResetEventを使用します。

 // machine A
 var event = new ManualResetEvent(false);
 B_Listener.OnChanged += delegate { event.Set(); }
 myDictionary.UpdateValue();
 event.WaitOne();
于 2010-01-21T06:46:32.070 に答える
0

私が正しく理解していれば、プログラムAは、プログラムBが値を更新するまで、追加のロジックを実行してはなりません。プログラムAは、UCalgaryからそのシステムからその更新の通知を受け取ることができます。

これらの仮定に基づいて、共有ディクショナリにデータを送信した後、Tick(a)ディクショナリの更新をチェックするか、(b)取得する変数をチェックするメソッドによってイベントが処理されるタイマーを開始することをお勧めします。共有辞書ライブラリからの通知によって設定されます。

更新が見つかったら、タイマーを停止し、新しく更新された値の処理を開始するメソッドを実行します。

タイマーは、提案した「無限ループ」とは異なりますが、処理のオーバーヘッドがほとんどなく、現実的な間隔(1秒、1分、24時間)でチェックするように設定でき、時間に合わせて設定できます。プログラムBまたは辞書で計画どおりに進まない場合は、アウトします。

于 2010-01-21T06:42:34.890 に答える
0

IPCの他の方法を使用しないと(この特定のライブラリに落ち着くように見えたので)、継続的なポーリングが唯一の方法であるように私には思えます。他のIPCメソッドを実装する意思がある(そしてできる)場合は、現在のライブラリの使用を中止し、プログラム間でデータを自分で渡す必要があります。

于 2010-01-21T06:35:14.700 に答える