c#进程间通讯
前言
进程间通讯有很多种,在这里做个汇总,面试前看一看。
命名管道(Named Pipes)
命名管道是一种高效的进程间通信方式,适用于本地机器上的进程通信。
服务端代码:
Console.WriteLine("Named Pipe Server is running...适合本地机器高效通讯"); using (var server = new NamedPipeServerStream("testpipe", PipeDirection.InOut)) { Console.WriteLine("等待客户端接入"); await server.WaitForConnectionAsync(); Console.WriteLine("客户端已接入"); //读取客户端消息 byte[] buffer = new byte[1024]; int bytesRead = await server.ReadAsync(buffer, 0, buffer.Length); var message = Encoding.UTF8.GetString(buffer, 0, bytesRead); Console.WriteLine("收到客户端消息" + message); //发送响应 string response = "Hello from server"; byte[] responseBuffer = Encoding.UTF8.GetBytes(response); await server.WriteAsync(responseBuffer, 0, responseBuffer.Length); Console.ReadLine(); }
客户端代码:
Console.WriteLine("Named Pipe Client is running..."); using (var client = new NamedPipeClientStream(".", "testpipe", PipeDirection.InOut)) { Console.WriteLine("等待连接到服务器"); await client.ConnectAsync(); Console.WriteLine("已连接到服务器"); //发送消息 string message = "你好,我是客户端"; byte[] buffer = Encoding.UTF8.GetBytes(message); await client.WriteAsync(buffer, 0, buffer.Length); //读取响应 byte[] responseBuffer = new byte[1024]; int bytesRead = await client.ReadAsync(responseBuffer, 0, responseBuffer.Length); var response = Encoding.UTF8.GetString(responseBuffer, 0, bytesRead); Console.WriteLine("收到服务器响应" + response); Console.ReadLine(); }
匿名管道(Anonymous Pipes)
匿名管道通常用于父子进程之间的通信,而命名管道可以用于任意进程之间的通信。
主要使用场景:父子进程之间通讯、简单的单向数据传输、临时通讯不需要跨多个进程共享。
class AnonymousPipeServer { static void Main(string[] args) { // 创建匿名管道 using (var pipeServer = new AnonymousPipeServerStream(PipeDirection.Out, HandleInheritability.Inheritable)) { Console.WriteLine("Parent process is running..."); // 启动子进程 var processStartInfo = new ProcessStartInfo("AnonymousPipeClient.exe"); processStartInfo.Arguments = pipeServer.GetClientHandleAsString(); processStartInfo.UseShellExecute = false; using (var childProcess = Process.Start(processStartInfo)) { // 发送消息给子进程 using (var writer = new StreamWriter(pipeServer)) { writer.AutoFlush = true; writer.WriteLine("Hello from parent process!"); } // 等待子进程结束 childProcess.WaitForExit(); } } } }
客户端
using System; using System.IO; using System.IO.Pipes; class AnonymousPipeClient { static void Main(string[] args) { // 获取父进程传递的管道句柄 string pipeHandle = args[0]; using (var pipeClient = new AnonymousPipeClientStream(PipeDirection.In, pipeHandle)) { Console.WriteLine("Child process is running..."); // 读取父进程发送的消息 using (var reader = new StreamReader(pipeClient)) { string message = reader.ReadLine(); Console.WriteLine($"Received from parent: {message}"); } } } }
内存映射文件(Memory-Mapped Files)
内存映射文件允许多个进程共享内存区域,适合大数据量的高效传输。
写入端
using System.IO.MemoryMappedFiles; //内存映射文件允许多个进程共享内存区域,适合大数据量的高效传输。 Console.WriteLine("内存映射文件写入者启动~"); //创建一个内存映射文件 using (var mmf = MemoryMappedFile.CreateOrOpen("testmap", 10000)) { //创建一个视图访问器 using (var accessor = mmf.CreateViewAccessor()) { Console.WriteLine("内存映射文件已创建,等待读取者接入"); Console.ReadLine(); Console.WriteLine("读取者已接入,开始写入数 据"); var message = "Hello from writer"; //写入数据 var array = System.Text.Encoding.UTF8.GetBytes(message); accessor.WriteArray(0, array, 0, array.Length); Console.WriteLine("数据写入完成"); Console.ReadLine(); } }
读取端
using System.IO.MemoryMappedFiles; using System.Text; Console.WriteLine("内存映射文件读取者启动"); using (var mmf = MemoryMappedFile.OpenExisting("testmap")) { Console.WriteLine("内存映射文件已经打开"); using (var accessor = mmf.CreateViewAccessor()) { var buffer = new byte[1000]; accessor.ReadArray(0, buffer, 0, buffer.Length); string message = Encoding.UTF8.GetString(buffer); Console.WriteLine("读取到数据:" + message); Console.ReadLine(); } }
IpcChannel
IpcChannel
是一种基于 .NET Remoting 的进程间通信方式,性能较高,适合同一台机器上的进程通信。但是仅适用于 .NET Framework:IpcChannel 和 .NET Remoting 不适用于 .NET Core 和 .NET 5+。.NET Remoting 不支持现代的安全机制,建议仅在受信任的环境中使用。
定义个公共库
public class RemoteObject : MarshalByRefObject { public string SayHello(string name) { return $"Hello, {name}!"; } }
服务端
static void Main(string[] args) { // 创建并注册 IpcChannel IpcServerChannel channel = new IpcServerChannel("MyIpcChannel"); ChannelServices.RegisterChannel(channel, false); // 注册远程对象 RemotingConfiguration.RegisterWellKnownServiceType( typeof(RemoteObject), // 远程对象类型 "RemoteObject.rem", // 远程对象 URI WellKnownObjectMode.Singleton); // 单例模式 Console.WriteLine("Server is running. Press Enter to exit..."); Console.ReadLine(); }
客户端
static void Main(string[] args) { // 创建并注册 IpcChannel IpcClientChannel channel = new IpcClientChannel(); ChannelServices.RegisterChannel(channel, false); // 获取远程对象 RemoteObject remoteObject = (RemoteObject)Activator.GetObject( typeof(RemoteObject), // 远程对象类型 "ipc://MyIpcChannel/RemoteObject.rem"); // 远程对象 URI // 调用远程方法 string response = remoteObject.SayHello(" 我是服务器"); Console.WriteLine($"Received from server: {response}"); Console.WriteLine("Press Enter to exit..."); Console.ReadLine(); }
WCF
适合复杂的通信场景,支持多种协议。
Socket
适合需要高度自定义的网络通信。
gRPC
合高性能、跨语言的 RPC 通信。
gRPC在.net中的使用 - chenxizhaolu - 博客园
HttpChannel
TcpChannel
Win32 Api SendMessage
Mutex信号量
代码地址:https://gitee.com/xiaoqingyao/ipcdemo.git
引用:
c#多进程通讯,今天,它来了 - 四处观察 - 博客园
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App
2018-03-04 无法连接到已配置的web服务器