2016-02-08 2 views
-2

Использование .NET 4, wpf C#, я передаю значения возвращаемых методов и параметры между двумя процессами.Inter-process communication sample-server & client C#

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

Мне было интересно сначала, как это должно быть закодировано, весь процесс, включая новый экземпляр, располагать, закрывать ... внутри цикла?

Является единственным доступным типом данных для межпроцессной связи, передаваемой как строка (неэффективная)?

public void client() 
{ 
    for (int i = 0; i < 2; i++) 
    { 
     System.IO.Pipes.NamedPipeClientStream pipeClient = 
      new System.IO.Pipes.NamedPipeClientStream(".", "testpipe", 
          System.IO.Pipes.PipeDirection.InOut, System.IO.Pipes.PipeOptions.None); 

     if (pipeClient.IsConnected != true) 
     { 
      pipeClient.Connect(550); 
     } 

     System.IO.StreamReader sr = new System.IO.StreamReader(pipeClient); 
     System.IO.StreamWriter sw = new System.IO.StreamWriter(pipeClient); 

     string status; 
     status = sr.ReadLine(); 

     if (status == "Waiting") 
     { 
      try 
      { 
       sw.WriteLine("param1fileName.cs,33" + i); 
       sw.Flush(); 
       pipeClient.Close(); 
      } 
      catch (Exception ex) { throw ex; } 
     } 
    } 
} 


public string server() 
{ 
    NamedPipeServerStream pipeServer = null; 
    do 
    { 
     try 
     { 
      pipeServer = new NamedPipeServerStream("testpipe", PipeDirection.InOut, 4); 

      StreamReader sr = new StreamReader(pipeServer); 
      StreamWriter sw = new StreamWriter(pipeServer); 

      System.Threading.Thread.Sleep(100); 
      pipeServer.WaitForConnection(); 
      string test; 
      sw.WriteLine("Waiting"); 
      sw.Flush(); 
      pipeServer.WaitForPipeDrain(); 
      test = sr.ReadLine(); 
      if (!string.IsNullOrEmpty(test)) 
       try 
       { 
        System.Windows.Application.Current.Dispatcher.Invoke(new Action(() => MbxTw.Show(Convert.ToInt32(test.Split(',')[1]), test.Split(',')[0], "method()", "Warning!! - " + "content")), System.Windows.Threading.DispatcherPriority.Normal); 
       } 
       catch (Exception e) 
       { 
       } 
     } 

     catch (Exception ex) { 
      throw ex; } 

     finally 
     { 
      pipeServer.WaitForPipeDrain(); 
      if (pipeServer.IsConnected) { pipeServer.Disconnect(); } 
     } 
    } while (true); 
} 
+0

Нет на все вопросы, но это не полезно вообще. Прочитайте [ask] и задайте лучший вопрос. – Amit

+0

Доступный тип данных _only_ для IPC - _byte_. Эти байты могут представлять все, что вы хотите, но поток в потоке только отправляет/принимает байты. См. «BitConverter» для вспомогательных методов обработки других типов данных. Кажется, что в вашем сообщении не существует фактического утверждения _problem. Если у вас есть рабочий код, кто-то не может сказать вам, как его исправить. Если вам нужно что-то исправить, предоставьте хороший [mcve], который надежно воспроизведет проблему, а также четкое описание проблемы. –

+0

@PeterDuniho спасибо за ваше время и детство! , он все еще в самом начале, но не могли бы вы кратко проверить мой ответ? –

ответ

0

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

Представляю окончательное разделение-глобальное приложение-взаимодействие между процессами

любые мысли на код будут очень благодарны!

public class MMFinterComT 
{ 
    public EventWaitHandle flagCaller1, flagCaller2, flagReciver1, flagReciver2; 

    private System.IO.MemoryMappedFiles.MemoryMappedFile mmf; 
    private System.IO.MemoryMappedFiles.MemoryMappedViewAccessor accessor; 

    public virtual string DepositChlName { get; set; } 
    public virtual string DepositThrdName { get; set; } 
    public virtual int DepositSize { get; set; } 
    private System.Threading.Thread writerThread; 
    private bool writerThreadRunning; 


    public int ReadPosition { get; set; } 
    public List<string> statusSet; 
    private int writePosition; 
    public int WritePosition 
    { 
     get { return writePosition; } 
     set 
     { 
      if (value != writePosition) 
      { 
       this.writePosition = value; 
       this.accessor.Write(WritePosition + READ_CONFIRM_OFFSET, true); 
      } 
     } 
    } 

    private List<byte[]> dataToSend; 

    private const int DATA_AVAILABLE_OFFSET = 0; 
    private const int READ_CONFIRM_OFFSET = DATA_AVAILABLE_OFFSET + 1; 
    private const int DATA_LENGTH_OFFSET = READ_CONFIRM_OFFSET + 1; 
    private const int DATA_OFFSET = DATA_LENGTH_OFFSET + 10; 
    public IpcMMFinterComSF.MMFinterComTStatus IntercomStatus; 
    public MMFinterComT(string ctrIpcChannelNameStr, string ctrIpcThreadName, int ctrMMFSize) 
    { 
     this.DepositChlName = ctrIpcChannelNameStr; 
     this.Deposit Size = ctrMMFSize; 
     this.DepositThrdName = ctrIpcThreadName; 
     mmf = MemoryMappedFile.CreateOrOpen(DepositChlName, DepositSize); 
     accessor = mmf.CreateViewAccessor(0, DepositSize, System.IO.MemoryMappedFiles.MemoryMappedFileAccess.ReadWrite);//if (started) 
     //smLock = new System.Threading.Mutex(true, IpcMutxName, out locked); 
     ReadPosition = -1; 
     writePosition = -1; 
     this.dataToSend = new List<byte[]>(); 
     this.statusSet = new List<string>(); 
    } 
    public bool reading; 
    public byte[] ReadData; 
    public void StartReader() 
    { 
     if (this.IntercomStatus != IpcMMFinterComSF.MMFinterComTStatus._Null || ReadPosition < 0 || writePosition < 0) 
      return; 
     this.IntercomStatus = IpcMMFinterComSF.MMFinterComTStatus.PreparingReader; 

     System.Threading.Thread t = new System.Threading.Thread(ReaderThread); 
     t.IsBackground = true; 
     t.Start(); 

    } 
    private void ReaderThread(object stateInfo) 
    { 

      // Checks if there is something to read. 
     this.IntercomStatus = IpcMMFinterComSF.MMFinterComTStatus.TryingToRead; 
      this.reading = accessor.ReadBoolean(ReadPosition + DATA_AVAILABLE_OFFSET); 
      if (this.reading) 
      { 
       this.IntercomStatus = IpcMMFinterComSF.MMFinterComTStatus.ReadingData; 
       // Checks how many bytes to read. 
       int availableBytes = accessor.ReadInt32(ReadPosition + DATA_LENGTH_OFFSET); 
       this.ReadData = new byte[availableBytes]; 
       // Reads the byte array. 
       int read = accessor.ReadArray<byte>(ReadPosition + DATA_OFFSET, this.ReadData, 0, availableBytes); 

       // Sets the flag used to signal that there aren't available data anymore. 
       accessor.Write(ReadPosition + DATA_AVAILABLE_OFFSET, false); 
       // Sets the flag used to signal that data has been read. 
       accessor.Write(ReadPosition + READ_CONFIRM_OFFSET, true); 
       this.IntercomStatus = IpcMMFinterComSF.MMFinterComTStatus.FinishedReading; 
      } 
      else this.IntercomStatus = IpcMMFinterComSF.MMFinterComTStatus._Null; 

    } 

    public void Write(byte[] data) 
    { 
     if (ReadPosition < 0 || writePosition < 0) 
      throw new ArgumentException(); 
     this.statusSet.Add("ReadWrite:-> " + ReadPosition + "-" + writePosition); 



     lock (this.dataToSend) 
      this.dataToSend.Add(data); 

     if (!writerThreadRunning) 
     { 
      writerThreadRunning = true; 
      writerThread = new System.Threading.Thread(WriterThread); 
      writerThread.IsBackground = true; 
      writerThread.Name = this.DepositThrdName; 
      writerThread.Start(); 
     } 
    } 
    public void WriterThread(object stateInfo) 
    { 
     while (dataToSend.Count > 0 && !this.disposed) 
     { 
      byte[] data = null; 
      lock (dataToSend) 
      { 
       data = dataToSend[0]; 
       dataToSend.RemoveAt(0); 
      } 

      while (!this.accessor.ReadBoolean(WritePosition + READ_CONFIRM_OFFSET)) 
       System.Threading.Thread.Sleep(133); 

      // Sets length and write data. 
      this.accessor.Write(writePosition + DATA_LENGTH_OFFSET, data.Length); 
      this.accessor.WriteArray<byte>(writePosition + DATA_OFFSET, data, 0, data.Length); 

      // Resets the flag used to signal that data has been read. 
      this.accessor.Write(writePosition + READ_CONFIRM_OFFSET, false); 
      // Sets the flag used to signal that there are data avaibla. 
      this.accessor.Write(writePosition + DATA_AVAILABLE_OFFSET, true); 
     } 

     writerThreadRunning = false; 
    } 



    public virtual void Close() 
    { 

     if (accessor != null) 
     { 
      try 
      { 
       accessor.Dispose(); 
       accessor = null; 
      } 
      catch { } 
     } 

     if (this.mmf != null) 
     { 
      try 
      { 
       mmf.Dispose(); 
       mmf = null; 
      } 
      catch { } 
     } 

     disposed = true; 
     GC.SuppressFinalize(this); 
    } 
    private bool disposed; 

} 

и использование

instaciant один раз!

public static bool StartCurProjInterCom(IpcAccessorSetting curSrv, int DepoSize) 
{ 
    if(CurProjMMF ==null) 
    CurProjMMF = new MMFinterComT(curSrv.Channel.ToString(), curSrv.AccThreadName.ToString(), DepoSize); 
    CurProjMMF.flagCaller1 = new EventWaitHandle(false, EventResetMode.ManualReset, CurProjMMF.DepositThrdName); 
    CurProjMMF.flagCaller2 = new EventWaitHandle(false, EventResetMode.ManualReset, CurProjMMF.DepositThrdName); 
    CurProjMMF.flagReciver1 = new EventWaitHandle(false, EventResetMode.ManualReset, IpcAccessorThreadNameS.DebuggerThrd.ToString()); 

    CurProjMMF.ReadPosition = curSrv.AccessorSectorsSets.DepoSects.Setter.Read; 
    CurProjMMF.WritePosition = curSrv.AccessorSectorsSets.DepoSects.Setter.Write; 
    Console.WriteLine("MMFInterComSetter.ReadPosition " + CurProjMMF.ReadPosition); 
    Console.WriteLine("MMFInterComSetter.WritePosition " + CurProjMMF.WritePosition); 

    CurProjMMF.StartReader(); 

    return true; 
} 

использование многих

public static void StartADebugerInterComCall(IpcCarier SetterDataObj) 
{ 
    IpcAccessorSetting curSrv = new IpcAccessorSetting(IpcMMf.IPChannelS.Debugger, IpcAccessorThreadNameS.DebuggerThrdCurProj, 0, 5000); 
    StartCurProjInterCom(curSrv, 10000); 

    var dataW = SetterDataObj.IpcCarierToByteArray();//System.Text.Encoding.UTF8.GetBytes(msg); 
    CurProjMMF.Write(dataW); 
    CurProjMMF.flagReciver1.Set(); 
    CurProjMMF.flagCaller1.WaitOne(); 
    CurProjMMF.flagCaller1.Reset(); 
} 
Смежные вопросы