0

多くの一般的なクライアントが独自のシステムと通信するために使用する通信 API を開発しています。

このプロプライエタリ システムは API を公開し、特定のクラスを使用してこのシステムからメッセージを送信および待機します。明らかに、システムはイベントを使用してメッセージの準備ができていることを警告します。イベントの名前は OnMessageArrived です。

私の考えは、単純な SendSyncMessage(message) メソッドを公開して、ユーザー/クライアントが単純にメッセージを送信し、メソッドが応答を返すのを助けることです。

クライアント:

using ( Communicator c = new Communicator() )
{
    response = c.SendSync(message);
}

communicator クラスは次のように行われます。

public class Communicator : IDisposable
{
    // Proprietary system object
    ExternalSystem c;

    String currentRespone;
    Guid currentGUID;
    private readonly ManualResetEvent _manualResetEvent;
    private ManualResetEvent _manualResetEvent2;

    String systemName = "system";
    String ServerName = "server";

    public Communicator()
    {
        _manualResetEvent = new ManualResetEvent(false);           

        //This methods are from the proprietary system API
        c = SystemInstance.CreateInstance();
        c.Connect(systemName , ServerName);
    }

    private void ConnectionStarter( object data )
    {
        c.OnMessageArrivedEvent += c_OnMessageArrivedEvent;

       _manualResetEvent.WaitOne();

        c.OnMessageArrivedEvent-= c_OnMessageArrivedEvent;

    }

    public String SendSync( String Message )
    {
        Thread _internalThread = new Thread(ConnectionStarter);
        _internalThread.Start(c);

        _manualResetEvent2 = new ManualResetEvent(false);

        String toRet;
        int messageID;

        currentGUID = Guid.NewGuid();

        c.SendMessage(Message, "Request", currentGUID.ToString());

        _manualResetEvent2.WaitOne();

        toRet = currentRespone;

        return toRet;
    }

    void c_OnMessageArrivedEvent( int Id, string root, string guid, int TimeOut, out int ReturnCode )
    {
        if ( !guid.Equals(currentGUID.ToString()) )
        {
            _manualResetEvent2.Set();
            ReturnCode = 0;
            return;
        }

        object newMessage;

        c.FetchMessage(Id, 7, out newMessage);

        currentRespone = newMessage.ToString();

        ReturnCode = 0;

        _manualResetEvent2.Set();
    }
}

私は本当に waithandle を使用することに慣れていませんが、メッセージを送信してイベントを待機するインスタンスを作成することを考えていました。イベントが到着するとすぐに、メッセージが期待どおりのものであるかどうかを確認し (一意の GUID を確認します)、そうでない場合は次のイベントを待ち続けます。これは、多くのクライアントが同時に作業している可能性があり (通常はこのようになっています)、それらが並行して動作するようにしたいからです。私が自分のものを実装したとき、現時点でクライアント1、クライアント2、およびクライアント3を実行すると、クライアント1が終了するとすぐにクライアント2がメッセージの送信を開始し、クライアント2が終了するとクライアント3が送信されます:私がしようとしているものではありません行う。

コードを修正してターゲットを取得するのを手伝ってもらえますか?

ありがとう!

4

1 に答える 1

0

autoResetEvent- メイン接続のライフ サイクルを制御します。呼び出してこのハンドルを解放する場所がわからないSet()ため、OnMessageArrivedイベントのサブスクライブが解除されます

autoResetEvent2-受信メッセージを制御します。予想される GUID を持つメッセージが受信された場合にのみ、このイベントを設定する必要があります。

if (guid == currentGUI.ToString())
{
   autoResetEvent2.Set(); 
}

また、変数にはより明確でわかりやすい名前を使用して、コードの記述と理解を容易にします。

于 2012-09-04T08:43:29.300 に答える