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#多进程通讯,今天,它来了 - 四处观察 - 博客园
posted @   chenxizhaolu  阅读(14)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App
历史上的今天:
2018-03-04 无法连接到已配置的web服务器
点击右上角即可分享
微信分享提示