2016-02-08 1 views
-2

En utilisant .NET 4, WPF C#, je passe des valeurs et des paramètres de retour de méthode entre les deux processus. Comme j'ai besoin de la connexion ouverte et active tout le temps, j'ai fait de mon mieux pour minimiser le code récurrent (dans la boucle) mais à moins de mettre tout ce code dans la boucle, ça n'a pas réussi (après le premier transfert de la connexion au serveur a été fermé), de sorte qu'il est ici, il fonctionne à plusieurs reprises.exemple du serveur de communication inter-processus et client C#

Je me demandais d'abord est-ce la façon dont il doit être codé, tout le processus, y compris la nouvelle instance, disposer, fermer ... dans la boucle?

Le seul type de données disponible pour la communication entre processus est-il transmis en tant que chaîne (inefficace)?

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

Pas sur toutes les questions, mais ce n'est pas utile du tout. Lisez [ask] et posez une meilleure question. – Amit

+0

Le type de données _only_ disponible pour IPC est _byte_. Ces octets peuvent représenter tout ce que vous voulez, mais le flux de pipe n'envoie/reçoit que des octets. Voir 'BitConverter' pour les méthodes d'assistance pour traiter d'autres types de données. Il ne semble pas y avoir une véritable déclaration de problème dans votre message. Si vous avez du code de travail, il n'est pas possible que quelqu'un vous dise comment le réparer. Si vous avez quelque chose à corriger, veuillez fournir un bon [mcve] qui reproduit fidèlement le problème, ainsi qu'une description claire du problème. –

+0

@PeterDuniho merci pour votre temps et votre enfant! , il est encore à son début, mais pourriez-vous s'il vous plaît vérifier brièvement sur ma réponse? –

Répondre

0

après une recherche approfondie sur la communication inter processus, je l'ai changé l'approche de l'utilisation de canaux nommés à la mémoire mappée fichiers, comme il est tout le gagnant de tours, pas besoin de recréer et plus rapide

Je vous présente l'ultime communication partitionnée-globale-application-inter-processus

toute pensée sur le code sera grandement appréciée!

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; 

} 

et de l'utilisation

instaciant une fois!

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

multiplies

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