在C# WPF開發(fā)中,內(nèi)存泄漏是一個(gè)常見且棘手的問題。內(nèi)存泄漏會(huì)導(dǎo)致應(yīng)用程序隨著時(shí)間的推移消耗越來越多的內(nèi)存,最終可能導(dǎo)致應(yīng)用程序崩潰或者系統(tǒng)性能下降。以下是一些常見的內(nèi)存泄漏原因以及相應(yīng)的排查和解決方法。
1. 事件訂閱
在 C# 中,實(shí)現(xiàn)兩個(gè)獨(dú)立執(zhí)行程序(EXE)之間的通信是一個(gè)常見的需求。這種通信可以通過多種方式實(shí)現(xiàn),包括但不限于命名管道、匿名管道、消息隊(duì)列、內(nèi)存映射文件、套接字(Sockets)以及使用 Windows API 如 SendMessage 等。本文將介紹幾種常用的方法,并提供示例代碼。
1. 使用命名管道進(jìn)行通信
命名管道是一種常用的進(jìn)程間通信(IPC)機(jī)制,允許不同進(jìn)程之間進(jìn)行雙向通信。
服務(wù)端示例代碼
using System;
using System.IO.Pipes;
using System.Text;
public class NamedPipeServer
{
public static void Main()
{
using (NamedPipeServerStream pipeServer = new NamedPipeServerStream("testpipe", PipeDirection.InOut))
{
Console.WriteLine("Waiting for client connection...");
pipeServer.WaitForConnection();
using (var reader = new StreamReader(pipeServer))
using (var writer = new StreamWriter(pipeServer))
{
writer.WriteLine("Hello from server");
writer.Flush();
string message = reader.ReadLine();
Console.WriteLine("Received from client: " + message);
}
}
}
}
客戶端示例代碼
using System;
using System.IO.Pipes;
using System.Text;
public class NamedPipeClient
{
public static void Main()
{
using (NamedPipeClientStream pipeClient = new NamedPipeClientStream(".", "testpipe", PipeDirection.InOut))
{
Console.WriteLine("Connecting to server...");
pipeClient.Connect();
using (var reader = new StreamReader(pipeClient))
using (var writer = new StreamWriter(pipeClient))
{
string message = reader.ReadLine();
Console.WriteLine("Received from server: " + message);
writer.WriteLine("Hello from client");
writer.Flush();
}
}
}
}
2. 使用匿名管道進(jìn)行通信
匿名管道是另一種 IPC 機(jī)制,通常用于父子進(jìn)程之間的通信。
服務(wù)端示例代碼
using System;
using System.IO.Pipes;
public class AnonymousPipeServer
{
public static void Main()
{
using (AnonymousPipeServerStream pipeServer = new AnonymousPipeServerStream(PipeDirection.Out))
{
Console.WriteLine("Writing to client...");
pipeServer.Write(new byte[] { 0x01, 0x02, 0x03, 0x04 }, 0, 4);
}
}
}
客戶端示例代碼
using System;
using System.IO.Pipes;
public class AnonymousPipeClient
{
public static void Main()
{
using (AnonymousPipeClientStream pipeClient = new AnonymousPipeClientStream(PipeDirection.In))
{
AnonymousPipeServerStream pipeServer = new AnonymousPipeServerStream(PipeDirection.Out, pipeClient);
pipeServer.DisposeLocalCopyOfClientHandle();
byte[] buffer = new byte[4];
int bytesRead = pipeClient.Read(buffer, 0, 4);
Console.WriteLine("Read {0} bytes from server.", bytesRead);
}
}
}
3. 使用 SendMessage 實(shí)現(xiàn)通信
SendMessage 是一個(gè) Windows API 函數(shù),可以用來在兩個(gè)獨(dú)立的 EXE 程序之間發(fā)送消息。
發(fā)送端示例代碼
using System;
using System.Runtime.InteropServices;
public class SendMessageSender
{
public const int WM_COPYDATA = 0x004A;
[DllImport("User32.dll", EntryPoint = "FindWindow")]
private static extern int FindWindow(string lpClassName, string lpWindowName);
[DllImport("User32.dll", EntryPoint = "SendMessage")]
private static extern int SendMessage(int hWnd, int Msg, int wParam, ref COPYDATASTRUCT lParam);
public struct COPYDATASTRUCT
{
public IntPtr dwData;
public int cbData;
[MarshalAs(UnmanagedType.LPStr)]
public string lpData;
}
public static void Main()
{
string message = "Hello from Sender";
COPYDATASTRUCT cds;
cds.dwData = IntPtr.Zero;
cds.cbData = message.Length + 1;
cds.lpData = message;
int hwnd = FindWindow(null, "Receiver Window Title");
SendMessage(hwnd, WM_COPYDATA, 0, ref cds);
}
}
接收端示例代碼
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
public class SendMessageReceiver : Form
{
public const int WM_COPYDATA = 0x004A;
public SendMessageReceiver()
{
// Set up the main window...
}
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_COPYDATA)
{
COPYDATASTRUCT cds = (COPYDATASTRUCT)Marshal.PtrToStructure(m.LParam, typeof(COPYDATASTRUCT));
string text = Marshal.PtrToStringAnsi(cds.lpData, cds.cbData - 1);
MessageBox.Show(text);
}
base.WndProc(ref m);
}
public static void Main()
{
Application.Run(new SendMessageReceiver());
}
}
結(jié)論
以上介紹了幾種在 C# 中實(shí)現(xiàn)兩個(gè) EXE 程序之間通信的方法。每種方法都有其適用場(chǎng)景和優(yōu)缺點(diǎn)。命名管道適用于需要全雙工通信的場(chǎng)景,匿名管道適用于父子進(jìn)程間的通信,而 SendMessage 則適用于簡(jiǎn)單的數(shù)據(jù)傳遞。開發(fā)者可以根據(jù)具體需求選擇合適的通信方式。
該文章在 2024/10/28 16:33:17 編輯過