重新审视 .NET 进程间通信






4.96/5 (30投票s)
XDMessaging 2.0 库提供了一种易于使用、零配置的替代现有 IPC 实现的方案。
引言
XDMessaging 库提供了一种易于使用、零配置的同机通信解决方案。它为跨应用程序和进程边界广播和接收消息提供了一个简单的 API。
版本 1.0 最初是为了使用低级别的Windows Messaging并为基于 Windows Forms 的应用程序提供高性能解决方案而开发的。然而,使用Windows Messages的限制在于它无法与非 Forms 应用程序进行通信,例如没有自己的消息泵的 Windows 服务。
版本 2.0 现在进一步扩展了该库,并提供了第二种基于文件 IO的传输模式用于消息传递。新的 IOStream
模式可用于与 Windows 服务、控制台应用程序通信,并继续适用于基于 Forms 的应用程序。
该库允许使用用户定义的伪通道来发送和接收消息。任何应用程序都可以向任何通道发送消息,但必须先在该通道注册为监听器才能接收。通过这种方式,开发人员可以快速、以编程方式设计他们的应用程序如何更好地协同工作。
优点
XDMessaging 库相对于 WCF、.NET Remoting、Sockets、NamedPipes 和 MailSlots 等其他 IPC 技术具有一些优势。首先,该库不需要服务器-客户端关系,因为进程之间没有物理连接。
使用 XDMessaging,消息可以由多个应用程序广播,并由多个监听器以断开连接的方式即时接收。MailSlots 在此功能上最为接近;然而,我发现它存在一些限制。虽然消息也是断开连接的,但无法预先查看消息,一旦消息被读取,它就会从 MailSlot 中删除。这对于广播消息非常有用,但接收消息仅限于单个客户端。另一个限制是消息不是即时的,需要轮询 MailSlot。
值得注意的是,大多数现有的 IPC 实现都需要打开特定端口并进行一些繁琐的设置配置才能使其正常工作。有了 XDMessaging,无需任何配置;API 使用伪通道来确定消息的发送位置以及接收哪些消息。缺点是通信仅限于单台机器,因此对于网络通信,WCF 等其他 IPC 技术则更为合适。
使用库
要使用该库,请创建 IXDBroadcast
的实例,并使用它向命名通道发送消息。然后,您可以创建 IXDListener
的实例以在特定通道上接收消息。通道是任意字符串,用于表示一个通道,不区分大小写。
在创建广播和监听器实例之前,您必须首先决定要为库使用哪种传输模式。有两种模式如下,每种模式都有其优势。
传输模式
IOStream
:此模式使用基于文件的 IO,通过共享目录广播消息。监听器类中使用FileSystemWatcher
来监视更改并触发包含广播消息的MessageReceived
事件。此模式可用于 Windows 服务、控制台应用程序和基于 Windows Forms 的应用程序。每个通道都在文件系统上创建单独的目录。临时目录应可供所有进程访问,无需手动配置。WindowsMessaging
:此模式使用WM_COPYDATA
Windows 消息在应用程序之间复制数据。广播实现将 Windows 消息直接发送到监听器实例上的隐藏窗口,该窗口会分派包含复制数据的MessageReceived
事件。通过添加/删除 Windows 属性来创建通道。这是基于 Windows Forms 的应用程序的最优性能解决方案,但不能用于 Windows 服务、控制台应用程序或其他没有消息泵的应用程序。
注意:使用特定模式广播的消息只能由使用同一模式监听器的应用程序读取。例如,IOStream
监听器无法读取以 WindowsMessaging
模式广播的消息。
有关在 Windows Forms 应用程序或 Windows 服务中使用该库的更多信息,请参阅随附的示例应用程序。
示例
示例:以特定模式发送消息
// Create an instance of IXDBroadcast using IOStream mode
IXDBroadcast broadcast = XDBroadcast.CreateBroadcast(XDTransportMode.IOStream);
// or create an instance of IXDBroadcast using WindowsMessaging mode
IXDBroadcast broadcast = XDBroadcast.CreateBroadcast(XDTransportMode.WindowsMessaging);
// Send shutdown message to a channel named commands
broadcast.SendToChannel("commands", "shutdown");
示例:监听特定通道上的消息
// Create our listener instance using IOStream mode
IXDListener listener = XDListener.CreateListener(XDTransportMode.IOStream);
// or create our listener using WindowsMessaging mode
IXDListener listener = XDListener.CreateListener(XDTransportMode.WindowsMessaging);
// Register channels to listen on
listener.RegisterChannel("events");
listener.RegisterChannel("status");
listener.RegisterChannel("commands");
// Stop listening on a specific channel
listener.UnRegisterChannel("status");
示例:处理消息
// Attach an event handler to a listener instance
listener.MessageReceived+=XDMessageHandler(this.listener_MessageReceived);
// process the message
private void listener_MessageReceived(object sender, XDMessageEventArgs e)
{
// e.DataGram.Message is the message
// e.DataGram.Channel is the channel name
switch(e.DataGram.Message)
{
case "shutdown":
this.Close();
break;
}
}
延伸阅读
历史
- 2009 年 12 月 12 日:初次发布
- 2009 年 12 月 16 日:优化性能
- 2010 年 1 月 4 日:通过 MailSlots 添加网络传播支持