我正在开发一个通信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完成:不是我正在尝试做。
你能帮助我修改我的代码并获得我的目标吗?
谢谢!
答案 0 :(得分:0)
autoResetEvent
- 控制主连接生命周期。通过调用Set()
,我看不到您释放此句柄的位置,因此OnMessageArrived
事件已取消订阅
autoResetEvent2
- 控制收到消息,只有收到预期GUID的消息时才应设置此事件,基本上只是
if (guid == currentGUI.ToString())
{
autoResetEvent2.Set();
}
还为变量使用更清晰和描述性的名称,以便更容易编写和理解代码