问题
I have two .net applications that run on the same machine. The first application is the 'Engine'. It builds images - image's size is about 4M. The second applications is the 'Viewer'. It shows the images which the 'Engine' sends. The engine sends images every 10-15 seconds.
My question is what is the bast way to pass the images from the engine to the viewer. Currently, I'm using FileSystem for this. The Engine writes the image to file system folder and the viewer getting this file using FileSystemWatcher.
Is that approach ok? Is that reliable?
回答1:
There is number of good options:
- Message Queue
- Named Pipes (directly)
- Memory mapped files
- WCF on Named Pipes or MSMQ
Any of those is more than fast enough so I would suggest easiest to implement.
Message Queue (MSMQ) in my opinion is simplest to use, gives you object transfer (as opposed to streams) and gives you optional transport persistence (useful in case sender or receiver is not running). All this is true for WCF over MSMQ but WCF means more overhead, complexity and configuration involved and no additional (in this case) value.
Send like this:
MessageQueue queue = new MessageQueue(".\\private$\\ImagesQueue");
Message msg = new Message
{
Formatter = new BinaryMessageFormatter(),
Body = myImage,
Label = "Image"
};
queue.Send(msg);
Receive:
MessageQueue queue = new MessageQueue(".\\private$\\ImagesQueue");
msg = queue.Receive(TimeSpan.FromMilliseconds(100));
if (msg != null)
{
msg.Formatter = new BinaryMessageFormatter();
myImage = (MyImage)msg.Body;
}
Queue needs to be created before use. You can do that when your application starts
Have this in your class:
private const string queueName = ".\\private$\\ImagesQueue";
And in application initialization/startup make sure you have your queue:
if (!MessageQueue.Exists(queueName)
{
MessageQueue myQueue = MessageQueue.Create(queueName);
}
With this queue mechanism, Engine does not have to wait for the Viewer to complete. This would much improve perceived performance because you can generate next image (actually number of them) while previous one is still being viewed. Not so easy to achieve with memory mapped files.
MSMQ is a standard Windows component but needs to be enabled in Windows Features.
回答2:
Since .NET Framework 4.0 you can use Memory Mapped Files for this, I believe it would be faster than file system based approach since you do not need expensive file system IO operations.
A memory-mapped file contains the contents of a file in virtual memory. This mapping between a file and memory space enables an application, including multiple processes, to modify the file by reading and writing directly to the memory. Memory-mapped files can be shared across multiple processes. Processes can map to the > same memory-mapped file by using a common name that is assigned by the process that created the file
So to share MMF across multiple processes you just need to share a MMF name, so you can consider following approach:
- Engine creates MMF file and share with Viewer just a name (string)
- View access MMF using MemoryMappedFile.OpenExisting(sharedName) method (see MSDN for an example accessing same MMF from different processes)
Useful links:
- Memory-Mapped Files
- Working with memory mapped files in .NET 4 - highly recommend reading this article which describes why MMF really
"is the most efficient way for multiple processes on a single machine to communicate with each other"
. Basically it show that all other IPC options are MMF-based.
(From the mentioned above article) If we check other IPC methods we can see the following architecture:
回答3:
Use ZeroMQ. It's very easy to use (easier than WCF if you just send one kind of message), doesn't have a lot of overhead, and in general a good solution to many interprocess communications problems.
回答4:
Yes, that's a valid approach. And assuming your code doesn't contain bugs, yes it's reliable.
But it is slow. If throughput is a concern, you may need to use Sockets (if you ever want to split the engine and viewer to different machines) or named pipes (for inter-process communications on the same machine).
来源:https://stackoverflow.com/questions/9410784/transfer-large-data-between-net-applications-on-same-computer