2009-11-08 3 views
6

J'ai une application où je lis depuis le port série, tout va bien, jusqu'à ce que je ferme l'application. Quand je clique sur le [X] l'application se bloque simplement, l'interface utilisateur: ne répond pas.C#: Façon correcte de fermer SerialPort avec Winforms

Je lis à partir du port dans le gestionnaire d'événements DataReceived, et je fermer le port quand FormClosed arrive:

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

Répondre

6

Serial Port hangs while closing

Ceci est un problème connu avec la classe SerialPort et décrit dans ce Product Feedback article ainsi que plusieurs discussions dans ces forums. Vous remarquerez peut-être le congédiement «fermé par conception».

+1

+1, dans ce lien avec la précédente question de l'OP. Mais pour une bonne réponse, vous pourriez avoir posté un bref résumé ** ici **. Supposons que cette page bouge? –

+2

INCROYABLE !!! c'est un bug connu dans le framework qui a été fermé par MS comme "fonctionne comme prévu !!!" +1 pour la référence – mfeingold

+0

LOL. Voir ma réponse ci-dessous. Il y a un bogue grave de code de port série dans le framework .NET mais c'est * NOT * it. –

9

Ce n'est pas un bug. La seule raison pour laquelle il se bloquerait lorsque vous le fermez est que dans le gestionnaire d'événements de votre objet SerialPort, vous synchronisez un appel avec le thread principal (généralement en appelant invoke). La méthode close de SerialPort attend que son thread EventLoopRunner déclenche les événements DataReceived/Error/PinChanged, mais puisque votre propre code dans l'événement attend également que le thread principal réponde, vous vous retrouvez dans une situation de verrouillage mort.

La raison pour laquelle le rapport de bogue a été fermé 'comme prévu' est que le 'bogue' est dans votre propre code.

+5

Oui, utilisez BeginInvoke, pas Invoke. –

+0

Merci les gars, c'est vrai ... BeginInvoke a résolu mon problème. – pm89

1

La solution la plus simple si vous ne voulez fermer le port que lorsque l'application se ferme, c'est de ne pas déranger Close() le port. Le port sera toujours fermé quand l'application disposera du port série. Le port sera disponible pour être ouvert à nouveau par votre application quand elle redémarre, ou par d'autres applications qui souhaitent utiliser le port.

+0

Il sera accroché à la disposition ainsi ... quand la disposition le ferme tellement jusqu'à devoir employer BeginInvoke. Bien sûr, cela n'a pas d'importance si vous fermez l'application. Cependant, cela n'a pas d'importance si vous ouvrez et fermez plusieurs ports série sans fermer votre application. – cb88

5

Si votre application appelle Invoke pour traiter des données reçues, essayez plutôt BeginInvoke.

Au lieu de:

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

utilisation:

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