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();
}
}
これがお役に立てば幸いです。