Al usar C# NamedPipeServerStream, en caso de que un cliente no envíe ningún mensaje final-pattern (como \ r \ n cuando el servidor lee con ReadLine()) NamedPipeServerStream Read métodos esperará para siempre y no Abort Los métodos() o Interupt() funcionarán en ese hilo.Tiempo de espera de lectura de servidor de canalizaciones con nombre
desde:
1) no Stream.ReadTimeout soportado para NamedPipeServerStream
2) Abort() o Interupt() no funciona en hilo
3) NamedPipeServerStream.Disconnect() de trabajo inferior
No está claro , ¿cómo configurar el tiempo de espera en las operaciones de lectura de NamedPipeServerStream?
Déjame presentarte un ejemplo. La especificación de IPC requiere un intercambio de cadenas terminadas en \ 0. Un cliente envía un mensaje, el servidor procesa el mensaje y como 'obligatorio' envía una respuesta. Si el cliente no envía \ 0 al final (el cliente no es nuestro, entonces no podemos garantizar la corrección de su funcionamiento), el método Read esperará por siempre y el cliente (ya que no lo controlamos) puede esperar para siempre para una respuesta también.
El siguiente es un ejemplo simplificado de una implementación:
public void RestartServer()
{
_pipeServerThread.Interrupt(); //doesn't affect Read wait
_pipeServerThread.Abort(); //doesn't affect Read wait
}
private void PipeServerRun(object o) //runs on _pipeServerThread
{
_pipeServer = new NamedPipeServerStream(_pipeName, InOut, 100,
PipeTransmissionMode.Message, PipeOptions.WriteThrough);
//_pipeServer.ReadTimeout = 100; //System.InvalidOperationException: Timeouts are not supporte d on this stream.
// Wait for a client to connect
while (true)
{
_pipeServer.WaitForConnection();
string request = ReadPipeString();
//... process request, send response and disconnect
}
}
/// <summary>
/// Read a \0 terminated string from the pipe
/// </summary>
private string ReadPipeString()
{
StringBuilder builder = new StringBuilder();
var streamReader = new StreamReader(_pipeServer);
while (true)
{
//read next byte
char[] chars = new char[1];
streamReader.Read(chars, 0, 1); // <- This will wait forever if no \0 and no more data from client
if (chars[0] == '\0') return builder.ToString();
builder.Append(chars[0]);
}
}
Entonces, ¿cómo poner el tiempo en NamedPipeServerStream operaciones de lectura?
Gracias, pero desafortunadamente no es la respuesta a mi pregunta. C# NamedPipeServerStream tiene un indicador IsMessageComplete que, según creo, depende del personal ERROR_MORE_DATA. Pero sucede que se establece en verdadero antes del final real del mensaje. Fue uno de los primeros que comprobamos. Si el cliente usa TransactNamedPipe parece que funciona, pero cuando uno usa la función C# NamedPipeClient o Write en WinApi, IsMessageComplete se puede configurar como verdadero antes de que se complete el mensaje. Creo que es, una vez más, debido a la naturaleza del transmisor de Stream. – MajesticRa
Sí, pero ¿por qué ejecutar la tubería en modo mensaje? En el modo de mensaje, se crea un mensaje de canalización para cada llamada de Win32 'Write'. Si sus clientes no se adhieren a esta convención, el modo de mensaje no tiene sentido. (Por cierto, ¿los clientes realmente configuran el extremo del cliente de la tubería al modo de mensaje?) –
Lamentablemente, el mundo no es perfecto y solo tengo las especificaciones. Nuestro cliente de prueba está en modo de mensaje. Pero no podemos garantizar esto sobre los clientes existentes. Parece que hay un problema con BeginRead también, pero sigo experimentando con él. – MajesticRa