【问题标题】:Several client waiting for the same event多个客户端等待相同的事件
【发布时间】:2012-09-04 08:38:40
【问题描述】:

我正在开发一种通信 API,供许多通用客户端与专有系统通信。

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

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

客户:

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 完成:不是我想要的做。

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

谢谢!

【问题讨论】:

    标签: c# multithreading api event-handling autoresetevent


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 我比较了字符串对象,因为我在事件中收到的 guid 是一个字符串。对于 _AutoResetEvent2 问题是我有点困惑。如果是“我的”指导,我想停下来等待并做一些逻辑,否则我想继续等待。你认为这是正确的方法吗?为什么现在有几个客户端被序列化了?
    • 谢谢!所以:我没有发布 dispose 方法以避免进一步的代码,但是在 Dispose 方法中,我断开了我的 c 和 Set() 的 manualResetEvent(以前的 autoResetEvet)。公共无效处置(){c。断开(); _manualResetEvent.Set(); }
    猜你喜欢
    • 2012-09-13
    • 2022-05-11
    • 2015-09-16
    • 1970-01-01
    • 1970-01-01
    • 2013-11-06
    • 1970-01-01
    • 1970-01-01
    • 2016-06-25
    相关资源
    最近更新 更多