2009-11-08 69 views
6

Tengo una aplicación donde leo desde el puerto serial, todo va bien, hasta que cierro la aplicación. Cuando hago clic en [X] la aplicación simplemente se cuelga, la IU: no responde.C#: Forma correcta de cerrar SerialPort con Winforms

leí desde el puerto del controlador de eventos DataReceived, y cerrar el puerto cuando FormClosed sucede:

private void MainForm_FormClosed(object sender, FormClosedEventArgs e) 
    { 
     mySerialPort.Close(); 
    } 

Respuesta

6

Serial Port hangs while closing

Este es un problema conocido de la clase SerialPort y se describen en este Product Feedback artículo, así como varios hilos en estos foros. Puede notar el despido "cerrado por diseño".

+1

+1, esto se relaciona con la pregunta anterior de la OP. Pero para una buena respuesta SO, podría haber publicado un breve resumen ** aquí **. Supongamos que esa página se mueve? –

+2

INCREÍBLE !!! este es un error conocido en el framework que, según MS, "funciona como está diseñado". +1 para la referencia – mfeingold

+0

LOL. Ver mi respuesta a continuación. Hay un serio error de código de puerto serie en .NET framework, pero esto es * NO *. –

9

No es un error.

La única razón por la que se colgaría al cerrarla es porque en el controlador de eventos de su objeto SerialPort, está sincronizando una llamada con el hilo principal (normalmente llamando a invocar). El método de cierre de SerialPort espera que su subproceso EventLoopRunner desencadene los eventos DataReceived/Error/PinChanged, pero dado que su propio código en el evento también está esperando la respuesta del subproceso principal, se encontrará con una situación de bloqueo inactivo.

El motivo por el cual el informe de error se cerró 'como se diseñó' es porque el 'error' está en su propio código.

+5

Sí, usa BeginInvoke, no Invoke. –

+0

Gracias chicos, es cierto ... BeginInvoke resolvió mi problema. – pm89

1

La solución más simple si solo quiere cerrar el puerto cuando se cierra la aplicación, es simplemente no molestarse en Cerrar() el puerto. El puerto aún se cerrará cuando la aplicación disponga del puerto serie. El puerto estará disponible para ser abierto nuevamente por su aplicación cuando se reinicie o por otras aplicaciones que deseen usar el puerto.

+0

También se colgará en el depósito ... cuando el depósito lo cierre, tendrá que usar BeginInvoke. Por supuesto, no importa si cierra la aplicación ... sin embargo, sí importa si abre y cierra múltiples puertos serie sin cerrar su aplicación. – cb88

5

Si su aplicación llama a Invoke para procesar los datos recibidos, intente llamar a BeginInvoke.

En lugar de:

this.Invoke(d, new object[] { s, tb }); 

uso:

this.BeginInvoke(d, new object[] { s, tb }); 
Cuestiones relacionadas