几个客户等待同一个事件

时间:2012-09-04 08:38:40

标签: c# multithreading api event-handling autoresetevent

我正在开发一个通信API,供很多通用客户使用,以便与专有系统进行通信。

这个专有系统公开了一个API,我使用一个特定的类来发送和等待来自这个系统的消息:很明显,系统提醒我使用事件准备好了消息。该事件名为OnMessageArrived。

我的想法是公开一个简单的SendSyncMessage(消息)方法,帮助用户/客户端简单地发送消息,该方法返回响应。

客户:

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

沟通者课程以这种方式完成:

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,客户端2在客户端1完成后立即开始发送消息,客户端3作为客户端2完成:不是我正在尝试做。

你能帮助我修改我的代码并获得我的目标吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

autoResetEvent - 控制主连接生命周期。通过调用Set(),我看不到您释放此句柄的位置,因此OnMessageArrived事件已取消订阅

autoResetEvent2 - 控制收到消息,只有收到预期GUID的消息时才应设置此事件,基本上只是

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

还为变量使用更清晰和描述性的名称,以便更容易编写和理解代码