2017-05-08 7 views
0

Ich verwende eine .net SerialPort als Eigenschaft in einer Klasse für die Kommunikation mit einiger Hardware. Wenn ich das Programm schließe, muss ich einen Stop-Befehl senden, bevor ich die Verbindung schließe.SerialPort-Eigenschaft wird geschlossen, wenn Klassendeconstructor ausgelöst wird

Ich dachte, dass der eleganteste Weg wäre, dies in meinem Dekonstruktor der Klasse zu tun, die ich geschrieben habe, aber ich musste herausfinden, dass meine SerialPort zu der Zeit geschlossen ist, als der Entscheider entlassen wurde und nicht wieder geöffnet werden kann.

Hier ist eine Testklasse I schrieb, die die gleichen Fehler produziert:

public class SerialPortTestClass 
{ 
    private System.IO.Ports.SerialPort ComPort { get; set; } 

    public SerialPortTestClass() 
    { 
     ComPort = new System.IO.Ports.SerialPort 
     { 
      BaudRate = 38400, 
      StopBits = System.IO.Ports.StopBits.One, 
      NewLine = ((char)19).ToString(), 
      Parity = System.IO.Ports.Parity.None, 
      Handshake = System.IO.Ports.Handshake.None, 
      RtsEnable = false, 
      ReadBufferSize = 512, 
      ReadTimeout = 5000, 
      ReceivedBytesThreshold = 1 
     }; 
    } 

    public void Connect(string port) 
    { 
     ComPort.PortName = port; 
     ComPort.Open(); 
    } 

    public void Disconnect() 
    { 
     var bytes = new byte[] { 83, 80, 32, 115, 54, 19 }; 
     ComPort.Write(bytes, 0, bytes.Length); 
     ComPort.Close(); 
    } 

    ~SerialPortTestClass() 
    { 
     if (ComPort.IsOpen) 
      Disconnect(); 
    } 
} 

Hat jemand eine Idee, warum der Serialport geschlossen ist und wie dieses Verhalten zu beheben?

+0

Das hat nichts zu tun mit der seriellen Schnittstelle, die folgende Methode Ihre MainWindow.xaml.cs das Hinzufügen würde. Dies liegt daran, dass der Destruktor beim Herunterfahren nicht aufgerufen wird. Um das zu lösen, muss man wissen, wie man die Klasse ausführt. Eine Konsolenanwendung? Internetanwendung? – fhogberg

+0

Die Klasse ist Teil einer WPF-Desktop-Anwendung. – dukemadcat

Antwort

0

Das Problem dabei ist, dass Sie sicherstellen müssen, dass der Code ausgeführt wird, wenn die Anwendung beendet wird. Destruktoren werden nicht garantiert beim App-Exit ausgeführt.

Eine Methode besteht darin, Ihre Klasse IDisposable zu machen. Wickeln Sie Ihre Instanz in einen using-Block und Sie werden sicher sein, dass Dispose() vor dem Beenden aufgerufen wird.

public class SerialPortTestClass : IDisposable 
{ 
    public void Dispose() 
    { 
     if (ComPort.IsOpen) 
      Disconnect(); 
    } 
    ... 

und Nutzung:

using (var sp = new SerialPortTestClass()) 
{ 
    //Your code goes here 
} 

Wenn das SerialPortTestClass in einem Fenster lebt, dann sollten Sie die disconnect aufrufen, wenn das Fenster geschlossen. Ich glaube, das passiert immer beim App-Ausgang. Für eine WPF-Anwendung, die

protected override void OnClosed(EventArgs e) 
{ 
    var vm = this.DataContext as MainWindowViewModel; 
    vm.SerialPort.Disconnect(); 
    base.OnClosed(e); 
} 
+0

Die Klasse, die den 'SerialPort' verwendet, läuft über die gesamte Laufzeit des Programms, so dass das Schreiben einer lokalen' using' Anweisung schwierig wäre. – dukemadcat

+0

Wo erstellen Sie die SerialPortTestClass und wie verweisen Sie darauf? – fhogberg

+0

Es wird deklariert und in meinem 'ViewModel' initialisiert, welches wie folgt referenziert wird: dukemadcat

Verwandte Themen