Какой самый простой метод межпроцессного взаимодействия между 2 процессами C #? - PullRequest
51 голосов
/ 09 февраля 2009

Я хочу общаться между родительским и дочерним процессами, написанными на C #. Он должен быть асинхронным, управляемым событиями. Я не хочу запускать поток в каждом процессе, который обрабатывает очень редкие сообщения.

Какое для этого лучшее решение?

Ответы [ 7 ]

34 голосов
/ 09 февраля 2009

Анонимные каналы .

Использование асинхронных операций с BeginRead / BeginWrite и AsyncCallback.

15 голосов
/ 28 апреля 2014

Если ваши процессы на одном компьютере, вы можете просто использовать stdio .

Это мое использование, снимок экрана веб-страницы:

var jobProcess = new Process();

jobProcess.StartInfo.FileName = Assembly.GetExecutingAssembly().Location;
jobProcess.StartInfo.Arguments = "job";

jobProcess.StartInfo.CreateNoWindow = false;
jobProcess.StartInfo.UseShellExecute = false;

jobProcess.StartInfo.RedirectStandardInput = true;
jobProcess.StartInfo.RedirectStandardOutput = true;
jobProcess.StartInfo.RedirectStandardError = true;

// Just Console.WriteLine it.
jobProcess.ErrorDataReceived += jp_ErrorDataReceived;

jobProcess.Start();

jobProcess.BeginErrorReadLine();

try
{
    jobProcess.StandardInput.WriteLine(url);
    var buf = new byte[int.Parse(jobProcess.StandardOutput.ReadLine())];
    jobProcess.StandardOutput.BaseStream.Read(buf, 0, buf.Length);
    return Deserz<Bitmap>(buf);
}
finally
{
    if (jobProcess.HasExited == false)
        jobProcess.Kill();
}

Обнаружение аргументов на главной

static void Main(string[] args)
{
    if (args.Length == 1 && args[0]=="job")
    {
        //because stdout has been used by send back, our logs should put to stderr
        Log.SetLogOutput(Console.Error); 

        try
        {
            var url = Console.ReadLine();
            var bmp = new WebPageShooterCr().Shoot(url);
            var buf = Serz(bmp);
            Console.WriteLine(buf.Length);
            System.Threading.Thread.Sleep(100);
            using (var o = Console.OpenStandardOutput())
                o.Write(buf, 0, buf.Length);
        }
        catch (Exception ex)
        {
            Log.E("Err:" + ex.Message);
        }
    }
    //...
}
8 голосов
/ 09 февраля 2009

Я бы предложил использовать Windows Communication Foundation:

http://en.wikipedia.org/wiki/Windows_Communication_Foundation

Вы можете передавать объекты назад и вперед, используя различные протоколы. Я бы предложил использовать двоичный протокол TCP.

5 голосов
/ 09 февраля 2009

Именованные каналы на WCF.

http://msdn.microsoft.com/en-us/library/ms733769.aspx

1 голос
/ 27 августа 2018

Существует также MSMQ (Microsoft Message Queuing), который может работать как в сети, так и на локальном компьютере. Хотя есть и лучшие способы общения, стоит посмотреть: https://msdn.microsoft.com/en-us/library/ms711472(v=vs.85).aspx

1 голос
/ 16 марта 2017

Там также COM .

Есть технические особенности, но я бы сказал, что преимущество заключается в том, что вы сможете вызывать методы, которые вы можете определить.

MSDN предлагает учебники по взаимодействию с C # COM. Пожалуйста, ищите, потому что эти ссылки меняются.

Чтобы начать прямо сейчас, пройдите здесь ...

0 голосов
/ 06 января 2019

Самое простое решение в C # для межпроцессного взаимодействия, когда безопасность не является проблемой и с учетом ваших ограничений (два процесса C # на одной машине) - это Remoting API. Теперь Remoting является устаревшей технологией (не такой, как устаревшая) и не рекомендуется для использования в новых проектах, но она работает хорошо и не требует большого количества пышности и обстоятельств для работы.

В MSDN есть отличная статья об использовании класса IpcChannel из среды удаленного взаимодействия (кредит Грег Бич для поиска здесь ) для настройки простого удаленного сервера. и клиент.

Я бы предложил сначала попробовать этот подход, а затем попытаться перенести ваш код в WCF (Windows Communication Framework). Который имеет несколько преимуществ (лучшая безопасность, кроссплатформенность), но обязательно более сложный. К счастью, у MSDN есть очень хорошая статья для переноса кода с Remoting на WCF .

Если вы хотите сразу же погрузиться с WCF, здесь есть отличное руководство .

...