c#跨进程通讯

5,714次阅读
没有评论

共计 3310 个字符,预计需要花费 9 分钟才能阅读完成。

进程间通讯是指在操作系统中,不同进程之间进行数据和信息进行交换的机制。在 C# 中,进程间通信可以通过多种方式实现,包括文件共享、命名管道、套接字、消息队列、远程过程调用(RPC)等。每种方法都有其特定的应用场景和优缺点。

在 C# 中,可以使用不同的技术来实现跨进程通信。以下是一些常见的跨进程通信技术和示例:

1. 命名管道(Named Pipes):

管道是一种半双工的通信机制,可以在同一台机器上的两个进程之间传输数据。管道分为匿名管道和命名管道。匿名管道通常用于父子进程之间的通信,而命名管道可以在不相关的进程之间进行通信。

csharp// 进程 1 - 发送消息 using (var pipeServer = new NamedPipeServerStream("myPipe")){// 等待客户端连接     pipeServer.WaitForConnection();
using (var sw = new StreamWriter(pipeServer))    {// 发送消息到客户端         sw.WriteLine("Hello from Process 1!");    }}

// 进程 2 - 接收消息 using (var pipeClient = new NamedPipeClientStream(".", "myPipe")){// 连接到服务器     pipeClient.Connect();
using (var sr = new StreamReader(pipeClient))    {// 从服务器接收消息 string message = sr.ReadLine();        Console.WriteLine("Received message:" + message);    }}
2. 共享内存(Shared Memory)共享内存允许两个或多个进程访问同一块内存区域,这是最快的 IPC 形式,因为数据不需要在进程之间复制。但是,共享内存通常需要额外的同步机制来避免数据冲突。// 使用 MemoryMappedFile 创建共享内存 
using (var mmf = MemoryMappedFile.CreateNew("MyMap", 1024)) 
{using (var accessor = mmf.CreateViewAccessor()) 
    {// 写入和读取数据} 
}

3. 消息队列(Message Queues)
消息队列允许进程通过发送和接收消息来进行通信。消息队列通常是独立于进程的,可以在不同的机器上运行。.NET Framework 提供了对 MSMQ(Microsoft Message Queuing)的支持。

// 使用 System.Messaging 库
// 安装 System.Messaging 包:dotnet add package System.Messaging
 
// 发送消息
using (var queue = new MessageQueue(@”.Private$MyQueue”))
{
    queue.Send(“Hello, World!”);
}
 
// 接收消息
using (var queue = new MessageQueue(@”.Private$MyQueue”))
{
    queue.Formatter = new XmlMessageFormatter(new[] {typeof(string) });
    var message = queue.Receive();
    string content = (string)message.Body;
    Console.WriteLine(content);

}

4. 信号量(Semaphores)
信号量是一种同步机制,可以用来控制多个进程对共享资源的访问。信号量通常与其他 IPC 机制一起使用。

// 使用 Semaphore 进行进程同步
 
Semaphore semaphore = new Semaphore(initialCount: 1, maximumCount: 1, name: “MySemaphore”);
 
semaphore.WaitOne(); // 访问共享资源
 
semaphore.Release();
}

5. 文件映射(File Mapping)
文件映射允许进程将文件内容映射到它们的地址空间中,从而实现数据共享。这通常与共享内存一起使用。

// 使用 FileStream 和 MemoryMappedFile 进行文件映射 
using (FileStream fs = new FileStream(“data.txt”, FileMode.Open)) 
{
    using (MemoryMappedFile mmf = MemoryMappedFile.CreateFromFile(fs, “MyMap”)) 
    {
    // 访问映射的文件数据 
    } 

}

6. Windows 套接字(Windows Sockets):

csharp// 进程 1 - 发送消息 using (var serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)){// 绑定到本地 IP 和端口     serverSocket.Bind(new IPEndPoint(IPAddress.Any, 1234));    serverSocket.Listen(1);
// 等待客户端连接 using (var clientSocket = serverSocket.Accept())    {// 发送消息到客户端 byte[] buffer = Encoding.UTF8.GetBytes("Hello from Process 1!");        clientSocket.Send(buffer);    }}

// 进程 2 - 接收消息 using (var clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)){// 连接到服务器     clientSocket.Connect("127.0.0.1", 1234);
// 接收消息 byte[] buffer = new byte[1024];int bytesRead = clientSocket.Receive(buffer);string message = Encoding.UTF8.GetString(buffer, 0, bytesRead);
    Console.WriteLine("Received message:" + message);}

7. Windows 消息(Windows Messages):​​​​​​​

csharp// 进程 1 - 发送消息 [DllImport("user32.dll", CharSet = CharSet.Auto)]private static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, string lParam);

// 发送自定义消息到进程 2 const int WM_COPYDATA = 0x004A;const int PROCESS2_ID = 12345; // 进程 2 的进程 ID

string message = "Hello from Process 1!";SendMessage(Process.GetProcessById(PROCESS2_ID).MainWindowHandle, WM_COPYDATA, 0, message);

// 进程 2 - 接收消息 protected override void WndProc(ref Message m){const int WM_COPYDATA = 0x004A;
if (m.Msg == WM_COPYDATA)    {        COPYDATASTRUCT copyData = (COPYDATASTRUCT)m.GetLParam(typeof(COPYDATASTRUCT));string message = Marshal.PtrToStringUni(copyData.lpData);        Console.WriteLine("Received message:" + message);    }
base.WndProc(ref m);}

原文地址: c# 跨进程通讯

    正文完
     0
    Yojack
    版权声明:本篇文章由 Yojack 于2024-09-30发表,共计3310字。
    转载说明:
    1 本网站名称:优杰开发笔记
    2 本站永久网址:https://yojack.cn
    3 本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长进行删除处理。
    4 本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
    5 本站所有内容均可转载及分享, 但请注明出处
    6 我们始终尊重原创作者的版权,所有文章在发布时,均尽可能注明出处与作者。
    7 站长邮箱:laylwenl@gmail.com
    评论(没有评论)