Перенос больших данных между приложениями .net на одном компьютере
У меня есть два приложения .net, которые запускаются на одном компьютере.
Первое приложение - "Двигатель". Он создает изображения - размер изображения составляет около 4M.
Второе приложение - "Viewer". Он показывает изображения, которые посылает "Двигатель".
Двигатель отправляет изображения каждые 10-15 секунд.
Мой вопрос заключается в том, что такое простой способ передать изображения из движка в программу просмотра.
В настоящее время я использую FileSystem для этого. Двигатель записывает изображение в папку файловой системы, а зритель получает этот файл с помощью FileSystemWatcher.
Этот подход подходит? Это надежный?
Ответы
Ответ 1
Существует множество хороших вариантов:
- Очередь сообщений
- Именованные каналы (напрямую)
- Файлы с отображением памяти
- WCF на именованных каналах или MSMQ
Любой из них более чем достаточно быстрый, поэтому я бы предложил сделать его проще всего.
Message Queue (MSMQ), на мой взгляд, прост в использовании, дает вам передачу объекта (в отличие от потоков) и дает вам необязательную переносимость (полезно, если отправитель или получатель не работает). Все это справедливо для WCF по сравнению с MSMQ, но WCF означает больше накладных расходов, сложность и конфигурацию и отсутствие дополнительного (в данном случае) значения.
Отправить вот так:
MessageQueue queue = new MessageQueue(".\\private$\\ImagesQueue");
Message msg = new Message
{
Formatter = new BinaryMessageFormatter(),
Body = myImage,
Label = "Image"
};
queue.Send(msg);
Прием:
MessageQueue queue = new MessageQueue(".\\private$\\ImagesQueue");
msg = queue.Receive(TimeSpan.FromMilliseconds(100));
if (msg != null)
{
msg.Formatter = new BinaryMessageFormatter();
myImage = (MyImage)msg.Body;
}
Очередь должна быть создана перед использованием. Вы можете сделать это, когда ваше приложение запустится
Сделайте это в своем классе:
private const string queueName = ".\\private$\\ImagesQueue";
И в инициализации/запуске приложения убедитесь, что у вас есть очередь:
if (!MessageQueue.Exists(queueName)
{
MessageQueue myQueue = MessageQueue.Create(queueName);
}
С помощью этого механизма очереди Engine не нужно ждать завершения просмотра. Это значительно улучшит воспринимаемую производительность, потому что вы можете сгенерировать следующее изображение (фактически количество из них), в то время как предыдущий все еще просматривается. Не так легко достичь с помощью файлов с отображением памяти.
MSMQ - это стандартный компонент Windows, но его необходимо включить в Windows.
Ответ 2
С .NET Framework 4.0 вы можете использовать файлы с памятью для этого, я считаю, что это будет быстрее, чем основанный на файловой системе подход, поскольку вам не нужны дорогостоящие операции ввода-вывода в файловой системе.
Файл с отображением памяти содержит содержимое файла в виртуальном Память. Это сопоставление между файлом и памятью позволяет приложение , включая несколько процессов, чтобы изменить файл на чтение и запись непосредственно в память. Файлы с отображением памяти могут совместно использоваться несколькими процессами. Процессы могут отображаться в тот же файл с отображением памяти, используя общее имя, назначенное процессом, создавшим файл
Итак, чтобы разделить MMF на несколько процессов, вам просто нужно предоставить имя MMF, чтобы вы могли рассмотреть следующий подход:
Полезные ссылки:
- Файлы с памятью
- Работа с файлами с отображением памяти в .NET 4 - настоятельно рекомендуем прочитать эту статью, в которой описывается, почему MMF действительно
"is the most efficient way for multiple processes on a single machine to communicate with each other"
. В основном это показывает, что все другие параметры IPC основаны на MMF.
(Из указанной выше статьи) Если мы проверим другие методы IPC, мы увидим следующую архитектуру:
![enter image description here]()
Ответ 3
Да, это действительный подход. И если ваш код не содержит ошибок, да, он надежный.
Но он медленный. Если пропускная способность является проблемой, вам может потребоваться использовать Sockets (если вы хотите разделить движок и средство просмотра на разные машины) или именованные каналы (для межпроцессных коммуникаций на одном компьютере).
Ответ 4
Используйте ZeroMQ. Он очень прост в использовании (проще, чем WCF, если вы просто отправляете сообщение одного типа), не имеет большого количества накладных расходов и, как правило, хорошее решение для многих проблем между процессами связи.