Würde mir bitte jemand erklären, wie man ein Event(?) beendet um den Serial.Port ordnungsgemäß zu schließen?
Ich öffne den Port, und bei eingehenden Daten startet DataReceivedHandler. Wenn ich nun btn_PortAbbrechen klicke, sollte dieser ja normalerweise schließen. Das funktionierte bisher relativ gut. Gelegentlich ist das Programm eingefroren allerdings.
Das hier sind Code-Schnipsel, der komplette Code wäre wohl nur unnütz lang:
using System;
using System.IO.Ports;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;
using System.Drawing;
namespace Schmid_Prüfprogramm
{
public partial class Schmid_PP : Form
{
SerialPort SerialPort = new SerialPort();
private delegate void threadSicher(string messung);
//Private Variablen ----------------------------------------------------------------------------------------------------------
string portName;
int baudRate = 19200;
public Schmid_PP()
{
//Funktionen die beim Start ausgeführt werden sollen hier rein.
InitializeComponent();
fillComPortComBoBox();
dateTimePicker1.Value = DateTime.Now;
btnLED_ReferenzStatus.BackColor = Color.Red;
}
private void btn_portVerbinden_Click(object sender, EventArgs e)
{
try
{
SerialPort.PortName = combox_Portliste.SelectedItem.ToString();
SerialPort.BaudRate = baudRate;
SerialPort.Open();
SerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
Console.WriteLine("Port geöffnet");
btn_portVerbinden.Enabled = false;
}
catch (Exception)
{
MessageBox.Show("Keinen Port ausgewählt", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void btn_PortAbbrechen_Click(object sender, EventArgs e)
{
SerialPort.Close();
lbl_Anzeige.Text = "N.A.";
lbl_Temperatur.Text = "N.A.";
btn_portVerbinden.Enabled = true;
}
public void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
//Console.WriteLine("Daten werden empfangen");
SerialPort serialPort = (SerialPort)sender;
string indata = serialPort.ReadLine();
updateMessung(indata);
}
private void updateMessung(string indata)
{
if (this.InvokeRequired)
{
this.Invoke(new threadSicher(updateMessung), new object[] { indata });
}
}
}
}
Ich denke, das nötigste ist mit drin.
10 Sekunden Google, evtl ist das hier auch der Fall
c-sharp-winform-freezing-on-serialport-close
Du musst sicherstellen, dass Du Dich im richtigen Thread befindest.
Und des weiteren: man sollte in C# seit Ewigkeiten (>10 Jahren) nicht mehr mit Threads direkt arbeiten, sondern mit Tasks.
Tasks übernehmen dabei auch die Synchronisation des Context.
Siehe [FAQ] Controls von Thread aktualisieren lassen (Control.Invoke/Dispatcher.Invoke)
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Setze mal ReadTimeout. Es kann sein, dass ReadLine ewig auf das Ende wartet.
Vielen Dank Abt! Habe das ganze mit BeginInvoke gemacht und es funktioniert wesentlich besser! Top 🙂
Wilfried: Das funktioniert soweit ganz gut. Warten tut da eigentlich nichts, wenn dann im µSekunden Bereich. Aber für meine drei Messungen/Sekunde reicht das ;D
Danke!