SerialPort
'da bazı zaman uyumsuz IO'yu yapan bir winform programım var. Bununla birlikte, SerialPort.Close() çağrısında donma gibi görünen programla periyodik olarak bir soruna rastlıyorum.C# SerialPort.Close üzerinde donma dondurma
Bu bir iş parçacığı güvenlik sorunu olduğunu düşünüyorum, ancak, nasıl düzeltileceğinden emin değilim. Bağlantı noktası açma/kapama işlevleriyle async DataReceived eylemcisini ekleme/çıkarma ve bağlantı noktasındaki giriş ve çıkış arabelleklerini atmayı denedim, ancak hiçbir şey yapmıyor gibi görünüyor. Ben önemli SerialPort
kod aşağıda düşünüyorum:
using System;
using System.Collections.Generic;
using System.IO.Ports;
public class SerialComm
{
private object locker = new object();
private SerialPort port;
private List<byte> receivedBytes;
public SerialComm(string portName)
{
port = new SerialPort(portName);
port.BaudRate = 57600;
port.Parity = Parity.None;
port.DataBits = 8;
port.StopBits = StopBits.One;
receivedBytes = new List<byte>();
}
public void OpenPort()
{
if(port!=null && !port.IsOpen){
lock(locker){
receivedBytes.Clear();
}
port.DataReceived += port_DataReceived;
port.Open();
}
}
public void ClosePort()
{
if(port!=null && port.IsOpen){
port.DataReceived -= port_DataReceived;
while(!(port.BytesToRead==0 && port.BytesToWrite==0)){
port.DiscardInBuffer();
port.DiscardOutBuffer();
}
port.Close();
}
}
private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
try{
byte[] buffer = new byte[port.BytesToRead];
int rcvdBytes = port.Read(buffer, 0, buffer.Length);
lock(locker){
receivedBytes.AddRange(buffer);
}
//Do the more interesting handling of the receivedBytes list here.
} catch (Exception ex) {
System.Diagnostics.Debug.WriteLine(ex.ToString());
//put other, more interesting error handling here.
}
}
}
GÜNCELLEME için
Teşekkür @ UI iş parçacığı ile kilitlenme durumu (This blog post nitelendirerek iyi bir iş yapar ve diğer birçok verir işaret Afrin cevabı iyi ipuçları), basit bir değişiklik yaptım ve henüz hatayı yeniden üretemedim! (bu genellikle çağırmak arayarak) çünkü SerialPort nesne
Sen ana iş parçacığı ile çağrı senkronize ediyoruz işleyicisi olay öyle kapattığınızda asarlar
private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
try{
byte[] buffer = new byte[port.BytesToRead];
int rcvdBytes = port.Read(buffer, 0, buffer.Length);
lock(locker){
receivedBytes.AddRange(buffer);
}
ThreadPool.QueueUserWorkItem(handleReceivedBytes);
} catch (Exception ex) {
System.Diagnostics.Debug.WriteLine(ex.ToString());
//put other, more interesting error handling here.
}
}
private void handleReceivedBytes(object state)
{
//Do the more interesting handling of the receivedBytes list here.
}
Ben özetle 'Oku' arasında 'SerialPort' içinde kilitlenme var, doğru anlamak emin olmak için 'Kapat' diyor? – chezy525
port_DataReceived olay işleyicisindeki UI öğesi güncellemelerini değiştirme şeklinizi değiştirmelisiniz, Invoke yerine güncellemek için BeginInvoke özelliğini kullanın veya çözümde açıklandığı gibi olayı işlemek için başka bir iş parçacığı kullanın. – Afshin
UI'nin verilerini farklı bir iş parçacığında işleme koymak sorunu çözmüş görünüyor. Teşekkürler! – chezy525