I use named pipes for inter-procedure communication between C # and Delphi. C # uses the System.IO.Pipes package, while Delphi uses Libby pipes.pas . Unfortunately, communication practically does not differ in high performance: Profiling showed me that the message occupies 72% of the entire execution environment, while the rest are used by calculations.
I was able to find one problem that could take resources. Unless I explicitly disconnect the connection to send the client to Delphi, C # does not receive any data at all.
Delphi (sending)
FClient1.Write(msg[1], Length(msg)); FClient1.FlushPipeBuffers; FClient1.WaitForReply(20); FClient1.Disconnect; // disconnect to signalize C
C # (receive)
// 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 just a single empty request while (tmp != null)// && result != tmp) { tmp = sr.ReadLine(); result += tmp; } // sleep, increment reconnect, write debugging... } stc.pipeServer.Close();
Even if I assume reconnecting is expensive, I'm not quite sure about it. One data stream (approximately 1/11 kb) takes 130 (respectively 270 ms for 11kb) in total (sending and receiving).
My question would be :
Is it necessary to forcefully disconnect pipes to signal that the client is written? As for my observations, this is only necessary when sending using libby's. Are there other possible causes for poor performance? Thanks in advance.
As an addition, they are sent here and get the other way around:
C # (submit)
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 (receive)
SetLength(S, Stream.Size); Stream.Read(S[1], Length(S)); FPipeBuffer := FPipeBuffer + S; { TODO 2 : switch case ID } // if the XML is complete, ie ends with the closing checksum if (IsFullMessage()) then begin // end reading, set flag FIsPipeReady := true; end