IPC - это то, что я использовал в прошлом для этого. И это удивительно легко. .Net remoting - это хороший вариант, но, к сожалению, это ограниченный вариант, потому что вы не можете, например, использовать его на CF.
Ниже приведена копия класса, который я использую для межпроцессного взаимодействия, вы можете использовать его в сочетании с MutEx, если хотите, но это не обязательно. Пока «pMappedMemoryName» и «pNamedEventName» одинаковы в обоих процессах, все должно работать нормально. Я пытался сделать это как можно более управляемым событием.
Просто используйте метод Poke для записи данных и метод Peek для их чтения, хотя я разработал его для автоматического запуска события при появлении новых данных. Таким образом, вы можете просто подписаться на событие IpcEvent и не беспокоиться о дорогих опросах.
public class IpcService {
private IServiceContext mContext;
const int maxLength = 1024;
private Thread listenerThread;
private readonly string mMappedMemoryName;
private readonly string mNamedEventName;
public event EventHandler<TextualEventArgs> IpcEvent;
private readonly bool mPersistantListener;
public IpcService(bool pPersistantListener)
: this(pPersistantListener, "IpcData", "IpcSystemEvent") {
;
}
public IpcService(bool pPersistantListener, string pMappedMemoryName, string pNamedEventName) {
mPersistantListener = pPersistantListener;
mMappedMemoryName = pMappedMemoryName;
mNamedEventName = pNamedEventName;
}
public void Init(IServiceContext pContext) {
mContext = pContext;
listenerThread = new Thread(new ThreadStart(listenUsingNamedEventsAndMemoryMappedFiles));
listenerThread.IsBackground = !mPersistantListener;
listenerThread.Start();
}
private void listenUsingNamedEventsAndMemoryMappedFiles() {
IntPtr hWnd = EventsManagement.CreateEvent(true, false, mNamedEventName);
while (listenerThread != null) {
if (Event.WAITOBJECT == EventsManagement.WaitForSingleObject(hWnd, 1000)) {
string data = Peek();
EventsManagement.ResetEvent(hWnd);
EventHandler<TextualEventArgs> handler = IpcEvent;
if (handler != null) handler(this, new TextualEventArgs(data));
}
}
EventsManagement.SetEvent(hWnd);
Thread.Sleep(500);
HandleManagement.CloseHandle(hWnd);
}
public void Poke(string format, params object[] args) {
Poke(string.Format(format, args));
}
public void Poke(string somedata) {
using (MemoryMappedFileStream fs = new MemoryMappedFileStream(mMappedMemoryName, maxLength, MemoryProtection.PageReadWrite)) {
fs.MapViewToProcessMemory(0, maxLength);
fs.Write(Encoding.ASCII.GetBytes(somedata + "\0"), 0, somedata.Length + 1);
}
IntPtr hWnd = EventsManagement.CreateEvent(true, false, mNamedEventName);
EventsManagement.SetEvent(hWnd);
Thread.Sleep(500);
HandleManagement.CloseHandle(hWnd);
}
public string Peek() {
byte[] buffer;
using (MemoryMappedFileStream fs = new MemoryMappedFileStream(mMappedMemoryName, maxLength, MemoryProtection.PageReadWrite)) {
fs.MapViewToProcessMemory(0, maxLength);
buffer = new byte[maxLength];
fs.Read(buffer, 0, buffer.Length);
}
string readdata = Encoding.ASCII.GetString(buffer, 0, buffer.Length);
return readdata.Substring(0, readdata.IndexOf('\0'));
}
private bool mDisposed = false;
public void Dispose() {
if (!mDisposed) {
mDisposed = true;
if (listenerThread != null) {
listenerThread.Abort();
listenerThread = null;
}
}
}
~IpcService() {
Dispose();
}
}
Надеюсь, это поможет.