c# serial-port port timeoutexception virtual-serial-port

C#virtual serial port timeoutexception on write



serial-port virtual-serial-port (2)

Tengo un problema con los puertos serie virtuales en C #: cuando llamo a la función Escribir, automáticamente lanza una excepción TimeOutException, pero el cliente recibe los datos.

Solo ocurre con los puertos virtuales (estoy usando Free Virtual Serial Ports desde HDDSoftware, con un puente COM12 <-> COM13). Abro COM12 con Visual Studio y el COM13 con Hercules. La aplicación arroja la excepción de tiempo de espera, pero Hercules recibe el mensaje.

No importa si configuro 1000 ms o 1000000 ms de tiempo de espera de puerto de Lectura / Escritura.

¡¡Gracias!!

using (SerialPort port = new SerialPort("COM13")) { // configure serial port port.BaudRate = 9600; port.DataBits = 8; port.Parity = Parity.None; port.StopBits = StopBits.One; port.Open(); port.ReadTimeout = 10000; byte[] buffer = Encoding.ASCII.GetBytes("HELLO WORLD"); try { port.Write(buffer, 0, buffer.Length); } catch(TimeoutException) { Console.WriteLine("Write timeout"); } Console.WriteLine(DateTime.Now.ToString("HH:mm:ss")); try { byte[] buf = new byte[100]; port.Read(buf, 0, 1); } catch(IOException) { Console.WriteLine("Read timeout"); } Console.WriteLine(DateTime.Now.ToString("HH:mm:ss")); }

Después de algunas pruebas (poner el Write en un try-catch), la operación Read también arroja un TimeOutException al instante.

Esto es lo que obtengo cuando ejecuto la prueba. Se supone que es: 12:16:06 (Tiempo de espera de lectura) 12:16:16


Como dijo Hans Passant, era un problema con el software COM virtual. ¡Probé con Virtual Serial Port de Eltima Software y funcionó bien!


port.Write(buffer, offset, count);

Depende del controlador del dispositivo decidir cómo implementarlo. Pero todos los que conozco siguen la regla de que la llamada WriteFile () subyacente puede devolver * lpNumberOfBytesWritten <nNumberOfBytesToWrite. O para decirlo de otra manera, la escritura no es "transaccional".

Un modelo mental decente es que Write () escribe un byte desde el búfer a la vez, cuente los tiempos. En algún momento, totalmente impredecible, cuando se escribe un byte más se parará cuando el búfer de transmisión del controlador se llene hasta su capacidad y no pueda almacenar otro byte. Eventualmente desencadenando la excepción.

De modo que parte del búfer seguirá llegando al otro extremo. No puede decir qué parte de la clase SerialPort. Un tiempo de espera es una falla de comunicación gruesa de la cual es bastante difícil recuperarse. Si eso es un show-stopper, entonces debes considerar escribir un byte a la vez (bueno, los puertos seriales son lentos) o prestar atención a WriteBufferSize - BytesToWrite para verificar si el buffer se ajusta e implementar tu propio tiempo de espera.