Перенос больших данных между приложениями .net на одном компьютере. - PullRequest
14 голосов
/ 23 февраля 2012

У меня есть два приложения .net, которые работают на одном компьютере.Первое приложение - «Двигатель».Он строит изображения - размер изображения около 4M.Второе приложение - «Просмотрщик».Он показывает изображения, которые посылает «Двигатель».Движок отправляет изображения каждые 10-15 секунд.

Мой вопрос заключается в том, как лучше всего передать изображения из движка зрителю.В настоящее время я использую FileSystem для этого.Механизм записывает изображение в папку файловой системы, и программа просмотра получает этот файл с помощью FileSystemWatcher.

Этот подход приемлем?Это надежно?

Ответы [ 4 ]

11 голосов
/ 23 февраля 2012

Поскольку в .NET Framework 4.0 вы можете использовать для этого файлы с отображением в памяти, я считаю, что это будет быстрее, чем подход, основанный на файловой системе, поскольку вам не нужны дорогостоящие операции ввода-вывода в файловой системе.

Файл с отображением в памяти содержит содержимое файла в виртуальном объем памяти. Это отображение между файлом и пространством памяти позволяет , включая несколько процессов , для изменения файла чтение и запись прямо в память. Отображенные в память файлы могут совместно использоваться несколькими процессами . Процессы могут отображаться в тот же файл с отображением в памяти, используя общее имя, назначенное процессом, создавшим файл

Таким образом, чтобы разделить MMF между несколькими процессами, вам просто нужно поделиться именем MMF, чтобы вы могли рассмотреть следующий подход:

  • Движок создает файл MMF и делится с Viewer только именем (строкой)
  • Просмотр MMF доступа с использованием MemoryMappedFile.OpenExisting (sharedName) метод (см. MSDN для примера доступа к одной и той же MMF из разных процессов)

Полезные ссылки:

(из упомянутой выше статьи) Если мы проверим другие методы IPC, мы увидим следующую архитектуру: enter image description here

7 голосов
/ 23 февраля 2012

Есть несколько хороших опций:

  • Очередь сообщений
  • Именованные каналы (напрямую)
  • Файлы с отображением в памяти
  • WCF в ИменованныхPipes или 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.

1 голос
/ 23 февраля 2012

Использование ZeroMQ . Он очень прост в использовании (проще, чем WCF, если вы просто отправляете один вид сообщений), не требует больших накладных расходов и в целом является хорошим решением многих проблем межпроцессного взаимодействия.

0 голосов
/ 23 февраля 2012

Да, это правильный подход.И если предположить, что ваш код не содержит ошибок, да, он надежен.

Но это медленно.Если пропускная способность является проблемой, вам может потребоваться использовать сокеты (если вы когда-либо захотите разделить движок и средство просмотра на разные машины) или именованные каналы (для межпроцессного взаимодействия на одной машине).

...