Problemas de desempenho de pipes nomeados
Eu estou usando pipes nomeados para comunicação inter-processual entre C # e Delphi. C # usa oSystem.IO.Pipes
pacote, enquanto Delphi faz uso deLibby's pipes.pas
. Infelizmente, a comunicação é apenas de alto desempenho: a criação de perfil mostrou que a comunicação ocupa 72% de todo o tempo de execução, o restante é usado por cálculos.
Consegui localizar um problema que poderia ocupar recursos: se eu não desconectar explicitamente a conexão do cliente de envio no Delphi,C # não recebe nenhum dado.
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 # (recebimento)// 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();
Mesmo que eu ache que a reconexão é cara, eu não tenho certeza disso. Um fluxo de dados (aproximadamente 1/11 kb) leva 130 (respectivamente 270ms para o total de 11kb) (envio e recepção).
Minha pergunta seria:
É necessário forçar a desconexão dos tubos para sinalizar que o cliente está escrevendo? No que diz respeito às minhas observações,isso só é necessário ao enviar com libby. Existem outras causas possíveis para o fraco desempenho? Desde já, obrigado.
Como complemento, aqui está o envio e recebimento feito vice-versa:
C # (envio) 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 (recebimento) 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