【发布时间】:2012-10-16 11:42:05
【问题描述】:
我正在使用命名管道在 C# 和 Delphi 之间进行过程间通信。 C# 使用System.IO.Pipes 包,而Delphi 使用Libby's pipes.pas。不幸的是,通信几乎是高性能的:分析显示通信占用了整个运行时间的 72%,其余用于计算。
我能够找到一个可能占用资源的问题:如果我没有在 Delphi 中显式断开发送客户端的连接,C# 根本不会收到任何数据。
德尔福(发送)
FClient1.Write(msg[1], Length(msg));
FClient1.FlushPipeBuffers;
FClient1.WaitForReply(20);
FClient1.Disconnect; // disconnect to signalize C# that the writing is finished
FClient1.Connect; // connect again to prevent synchronization problems
C#(接收)
// Wait for a client to connect
stc.pipeServer.WaitForConnection();
while (reconnect_attempts < MAX_RECONNECT_ATTEMPTS) //
{
string tmp = sr.ReadLine();
// if result is empty, try again for <MAX_RECONNECT_ATTEMPTS> times
// so you can eliminate the chance that there's just a single empty request
while (tmp != null)// && result != tmp)
{
tmp = sr.ReadLine();
result += tmp;
}
// sleep, increment reconnect, write debugging...
}
stc.pipeServer.Close();
尽管我猜重新连接很昂贵,但我并不完全确定。一个数据流(大约 1 / 11 kb)总共需要 130(11kb 分别为 270ms)(发送和接收)。
我的问题是:
是否有必要强制断开管道以表示客户端已完成写入?就我的观察而言,只有在使用 libby 发送时才有必要。性能不佳还有其他可能的原因吗?提前致谢。
另外,这里的发送和接收反之亦然:
C#(发送)
stc.pipeClient.Connect();
StreamWriter sw = new StreamWriter(stc.pipeClient);
//sw.AutoFlush = true;
sw.WriteLine(msg);
sw.Flush();
stc.pipeClient.WaitForPipeDrain(); // waits for the other end to read all bytes
// neither disconnect nor dispose
Delphi(接收)
SetLength(S, Stream.Size); Stream.Read(S[1], Length(S));
FPipeBuffer := FPipeBuffer + S; { TODO 2 : switch case ID }
// if the XML is complete, i.e. ends with the closing checksum
if (IsFullMessage()) then
begin
// end reading, set flag
FIsPipeReady := true;
end
【问题讨论】:
-
也许不是断开连接而是尝试发送换行符,以便 C# 端可以处理其
Readline();调用。 -
在字符串中添加 #13#10 形式的换行符没有帮助。从外观上看,C# 部分在断开连接之前无法识别任何数据。
-
究竟是什么吃掉了这 72%? C#/Delphi 发送/接收?
-
两边的全管道通信,即C# -> Delphi,反之亦然。
标签: c# delphi io named-pipes