【问题标题】:Inter-process communication sample-server & client C#进程间通信示例-服务器和客户端 C#
【发布时间】:2016-05-18 17:10:08
【问题描述】:

使用 .NET 4,wpf 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);
}

【问题讨论】:

  • 对所有问题都没有,但这根本没有用。阅读How to Ask 并提出更好的问题
  • IPC唯一可用的数据类型是byte。这些字节可以代表您想要的任何内容,但管道流仅发送/接收字节。有关处理其他类型数据的辅助方法,请参阅BitConverter。您的帖子中似乎没有实际的问题陈述。如果您有有效的代码,则不可能有人告诉您如何修复它。如果您有问题需要解决,请提供一个可靠的 minimal reproducible example 以可靠地重现问题,并清楚地说明问题所在。
  • @PeterDuniho 感谢您的时间和孩子! ,它仍处于开始阶段,但请您简单检查一下我的答案吗?

标签: c# wpf ipc


【解决方案1】:

在对进程间通信进行彻底研究后,我将方法从使用命名管道更改为内存映射文件, 因为它是所有回合的胜利者,无需重新创建它并且更快

我展示了最终的分区全局应用程序进程间通信

对代码的任何想法将不胜感激!

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;

}

和用法

瞬间!

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-06
    • 1970-01-01
    • 1970-01-01
    • 2021-03-02
    • 1970-01-01
    相关资源
    最近更新 更多