Как стать автором
Обновить

Комментарии 20

WCF разве не для таких задач предназначен?
Вы правы, и для таких. Но ответ на Ваш вопрос уже есть в статье.
Тут можно развести хороший такой холивар, опираясь на то что .NET ориентирован на абстрагирование от канала передачи данных и позволяет одинаково хорошо шарить объекты как по сети, так и между процессами. Но поскольку тема статьи – именно IPC, то попрошу этого не делать.
А чем Windows Communication Foundation не Inter-process Communication? Есть классика IPC в Windows — named pipes. IpcChannel — это старая обертка для них. NetNamedPipeBinding в WCF — новая. Никаких причин считать, что старый .net remoting в лице IpcChannel более IPCстей, чем WCF — нет))
Да, раньше я тоже пробовал IpcChannel, а позже WCF для общения с созданным подпроцессом…
Теперь делаю проще. Запускаю процесс:
var start = new ProcessStartInfo
{
	...
	UseShellExecute = false,
	RedirectStandardInput = true,
	RedirectStandardOutput = true
};

А затем, чтобы пообщаться с ним (в обе стороны, от папы-сыну, от сына-папе), сериализую сообщение, и у дочернего процесса жду:
Encoding.Default.GetString(Convert.FromBase64String(Console.ReadLine()));

От родительского шлю:
process.StandardInput.WriteLine(Convert.ToBase64String(mySerializedMessage));

А уж через консоль поддерживаются и синхронная и асинхронная модель обмена сообщениями.
Не видел ничего проще. Брат жив.

PS: По прежнему не хватает приличной имперсонации подпроцесса и завершения подпроцесса в случае исчезновения отца. Без финтов имею ввиду. На стековерфлоу обе задачи решаются через pinvoke.
Ну и обычного форка не хватает :)
Если нету handle'a на приемник (например посылаем сообщение в процесс, на который мы поставили хук), или передаем нечто более сложное чем обычная строка — то этот подход уже не пройдет.
Хотя я с Вами полностью согласен, для простых задач городить огород не стоит — чем проще решение, тем оно надежней.
Я там писал что сообщение (объект) я сначала сериализую в строку. А перевожу в base64 против всяких там переносов строк.
В этом плане от того же WCF/IPC ничем не отличается — везде нужно уметь сериализовать объект, чтобы передать другому.
Сразу не сообразил что Вы имели ввиду объект.
Жаль не пишут почему минусуют…
А то статья про «простой» IPC :) Может ещё проще есть способ?
Увы и ах, но минусовал не я.
Всего способов достаточно много (можно даже простой PostMessage использовать), некоторые упомянуты в статье.
Не на вас сокрушаюсь — я действительно ищу способ проще :)
Вы можете сделать Remoting поверх stdin/stdout, это очень, очень просто делается, и намного удобнее текстовых команд.
Не могли бы вы вкратце описать как. А то максимум на что у меня хватило фантазии, так это десериализировать входные данные и сериализировать выходные используя обычный XmlSerializer.
Ну вы можете получить из TextWriter-ов потоков stdin/stdout настоящий бинарный Stream и гонять байтмассивы, полученные через BinaryFormatter, который умеет нормально работать с сообщениями, генерируемыми RealProxy и RemotingServices.
Remoting вообще штука замечательная. Наследуетесь от RealProxy, и получаете на входе в Invoke объект, отражающий всю информацию о вызове метода, которую в дальнейшем можно использовать как угодно (натравить BinaryFormatter и отправить получателю, как это делают стандартные средства, реализовать свой механизм IPC, etc). А что ещё замечательнее, работает без проблем с Mono, чего нельзя сказать о WCF. Так же рекомендуется посмотреть в сторону ServiceStack.
Ничего хорошего про Remoting сказать не могу. В году 05-07 был популярен. Сейчас все WCF используют для новых проектов.
А как же AOP c использованием RealProxy?=)
Вообще, это медленно и заставляет наследоваться от MarshalByRefObject, в случае с AOP всё же лучше наэмитить классов-наследников.
Для IPC в рамках одной машины Remoting подходит идеально, у него нет недостатков, влияющих на этот сценарий использования. WCF не работает нормально с Mono. Посему ни на iOS, ни на андройде вы его нормально использовать не сможете. Не говоря уже о случаях с серверной частью на *nix. Так что для IPC через веб стоит использовать ServiceStack.
В свое время оказался в похожей ситуации и выбрал в качестве инструмента передачи данных сокеты. Если речь идет о межпроцесовом взаимодействии в рамках одной машины, это может выглядеть избыточно, но зато позволяет в любой момент перейти на связь между компьютерами. Тогда хотелось сделать что-то похожее на чат между клиентами, т.е. обеспечить асинхронную передачу сообщений. Взяв за основу сэмпл из какой-то статьи, удалось с помощью асинхронных операций соорудить очень приличную библиотечку, которую использую во многих проектах уже почти год и вообще не задумываюсь о проблеме межпроцессового взаимодействия.

Конечно, все время терзают смутные сомнения на счет того, что стоит разобраться с WCF, но никак руки не доходят…
Ничего сложного, обязательно разбирайтесь — как-никак, уже 2013-й на дворе :-).
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации