进程间通信示例服务器&;客户C#
我使用.NET4,wpf c#,在两个进程之间传递方法返回值和参数 由于我需要连接始终处于打开和活动状态,因此我已尽最大努力最小化重复出现的代码(在循环中),但除非我将整个代码放入循环中,否则它不会成功(在第一次将连接传输到服务器后关闭),因此在这里,它会重复工作 我想知道的是,首先,它应该是这样编码的,所有的过程包括新实例、dispose、close。。。在循环中 进程间通信作为字符串传递的唯一可用数据类型(效率低下)进程间通信示例服务器&;客户C#,c#,wpf,ipc,C#,Wpf,Ipc,我使用.NET4,wpf c#,在两个进程之间传递方法返回值和参数 由于我需要连接始终处于打开和活动状态,因此我已尽最大努力最小化重复出现的代码(在循环中),但除非我将整个代码放入循环中,否则它不会成功(在第一次将连接传输到服务器后关闭),因此在这里,它会重复工作 我想知道的是,首先,它应该是这样编码的,所有的过程包括新实例、dispose、close。。。在循环中 进程间通信作为字符串传递的唯一可用数据类型(效率低下) public void客户端() { 对于(int i=0;iMbxTw.
public void客户端()
{
对于(int i=0;i<2;i++)
{
System.IO.Pipes.NamedPipeClientStream pipeClient=
新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=新的System.IO.StreamReader(pipeClient);
System.IO.StreamWriter sw=新的System.IO.StreamWriter(pipeClient);
字符串状态;
status=sr.ReadLine();
如果(状态=“等待”)
{
尝试
{
sw.WriteLine(“param1fileName.cs,33”+i);
sw.Flush();
pipeClient.Close();
}
catch(异常ex){throw ex;}
}
}
}
公共字符串服务器()
{
NamedPipeServerStream pipeServer=null;
做
{
尝试
{
pipeServer=新名称PipeServerStream(“testpipe”,PipeDirection.InOut,4);
StreamReader sr=新的StreamReader(pipeServer);
StreamWriter sw=新StreamWriter(pipeServer);
系统线程线程睡眠(100);
WaitForConnection();
串试验;
西南书写线(“等待”);
sw.Flush();
WaitForPipeDrain();
test=sr.ReadLine();
如果(!string.IsNullOrEmpty(test))
尝试
{
System.Windows.Application.Current.Dispatcher.Invoke(新操作(()=>MbxTw.Show(Convert.ToInt32(test.Split(','))[1])、test.Split(',')[0]、“method()”、“Warning!!-”+“content”)、System.Windows.Threading.DispatcherPriority.Normal);
}
捕获(例外e)
{
}
}
捕获(例外情况除外){
抛出x;}
最后
{
WaitForPipeDrain();
如果(pipeServer.IsConnected){pipeServer.Disconnect();}
}
}虽然(正确);
}
在深入研究进程间通信后,我将使用命名管道的方法改为使用内存映射文件,
由于它是所有回合的赢家,因此无需重新创建它,而且速度更快
我介绍了最终的分区全局应用程序进程间通信
如果您对代码有任何想法,我们将不胜感激
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 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();
}
所有问题都没有,但那根本没用。阅读并提出更好的问题IPC唯一可用的数据类型是字节。这些字节可以表示您想要的任何内容,但管道流只发送/接收字节。有关处理其他类型数据的帮助器方法,请参见
BitConverter
。在你的帖子里似乎没有一个真正的问题陈述。如果你有工作代码,别人就不可能告诉你如何修复它。如果您有什么问题需要解决,请提供一个可靠地重现问题的良好文档,并清楚地描述问题所在。@PeterDuniho感谢您的时间和耐心,这仍然是它的开始,但你能简单地检查一下我的答案吗?
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();
}