You could use a combination of MemoryMappedFile
, Mutex
and EventWaitHandle
to manage this between processes.
The following example shows how it would work. In real code, the producer()
method would be in a different application from the consumer()
method, but this serves to illustrate an implementation:
using System;
using System.IO;
using System.IO.MemoryMappedFiles;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
void run()
{
Task.Run(() => consumer());
Task.Run(() => producer());
Console.WriteLine("Press <ENTER> to stop.");
Console.ReadLine();
}
static void producer()
{
using (var mmf = MemoryMappedFile.CreateOrOpen("MyMapName", 1024))
using (var view = mmf.CreateViewStream())
{
var writer = new BinaryWriter(view);
var signal = new EventWaitHandle(false, EventResetMode.AutoReset, "MyEventName");
var mutex = new Mutex(false, "MyMutex");
for (int i = 0; i < 100; ++i)
{
string message = "Message #" + i;
mutex.WaitOne();
writer.BaseStream.Position = 0;
writer.Write(message);
signal.Set();
mutex.ReleaseMutex();
Thread.Sleep(1000);
}
}
}
static void consumer()
{
using (var mmf = MemoryMappedFile.CreateOrOpen("MyMapName", 1024))
using (var view = mmf.CreateViewStream())
{
var reader = new BinaryReader(view);
var signal = new EventWaitHandle(false, EventResetMode.AutoReset, "MyEventName");
var mutex = new Mutex(false, "MyMutex");
while (true)
{
signal.WaitOne();
mutex.WaitOne();
reader.BaseStream.Position = 0;
var message = reader.ReadString();
Console.WriteLine("Received message: " + message);
mutex.ReleaseMutex();
}
}
}
static void Main()
{
new Program().run();
}
}
}
IMPORTANT: This implementation does not use a queue, so it is possible for the consumer to miss messages if it does not process them before a new message arrives.
If you must not miss any messages, you would have to use some kind of queuing implementation instead, for example MSMQ.
However, you could also consider using Windows Communications Foundation, which allows you to call remote methods in another process - but that might require more coupling between processes than you want.
Finally, another possibility is to use a Named Pipe
. I actually think this might be the best solution for you.
There's a Microsoft example showing server and client IPC using a named pipe here: http://msdn.microsoft.com/en-us/library/bb546085%28v=vs.110%29.aspx