2009-02-09 11 views
45

Chcę komunikować się między procesem nadrzędnym a potomnym, zarówno w języku C#. Powinien być asynchroniczny, sterowany zdarzeniami. Nie chcę uruchamiać wątku w każdym procesie, który obsługuje bardzo rzadką komunikację.Jaka jest najprostsza metoda komunikacji między procesami między procesami 2 C#?

Jakie jest najlepsze rozwiązanie?

+1

Zrobiłem artykuł na moim blogu o bardzo prostym przykładzie komunikacji między procesami przy użyciu nazwanych potoków w WCF. [https://dopeydev.com/wcf-interprocess-communication/](https://dopeydev.com/wcf-interprocess-communication/) –

Odpowiedz

9

Proponuję za pomocą Windows Communication Foundation:

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

można przekazać obiekty iz powrotem, należy użyć wielu różnych protokołów. Sugerowałbym użycie binarnego protokołu TCP.

+57

... więc, w jaki sposób jest to skomplikowane? – dfasdljkhfaskldjhfasklhf

+4

@ BPAndrew: Przepisywanie własnej wersji WCF? ;) – technophile

+50

Jeśli WCF jest "najprostszą metodą", naprawdę chcę się rozpłakać: P – kizzx2

13

Jeśli procesy w tym samym komputerze, możesz po prostu użyć stdio.

To jest mój zwyczaj, strona internetowa screenshooter:

 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(); 
     } 

Detect args na Main

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); 
     } 
    } 
    //... 
} 
+3

Nie działa jednak, jeśli proces docelowy musi mieć graficzny interfejs użytkownika, tzn. Jeśli parametr "ProcessStartInfo. UseShellExecute" ma wartość "true". W takim przypadku nie można przekierować standardowego wyjścia i błędu. –

+0

@GuidoDomenici Możesz go używać, gdy ma GUI ... –

+0

@JayCroghan Nie sądzę, że możesz go użyć, gdy ma GUI. Przynajmniej po uruchomieniu procesu klienta z aplikacji internetowej. – Balanikas

0

Jest też COM.

Istnieją kwestie techniczne, ale powiedziałbym, że zaletą jest to, że możesz wywoływać metody, które możesz zdefiniować.

MSDN oferuje samouczki w stylu C# COM. Proszę szukać, ponieważ te linki się zmieniają.

Aby zacząć rightaway iść here ...