SerialPort
でいくつかの非同期IOを実行するwinformプログラムがあります。しかし、私は定期的にSerialPort.Close()呼び出しでプログラムがフリーズしているように見えます。SerialPortでWinformがフリーズします。閉じる
私はスレッドセーフの問題だと思っていますが、もしあれば修正する方法がわかりません。私は、ポートのオープン/クローズ機能を使って非同期のDataReceivedハンドラを追加/削除しようとしましたが、ポートの入出力バッファを破棄しましたが、何もしないようです。私は重要なSerialPort
コードは以下のだと思う:アフリンの答えはUIスレッドでデッドロック状態を指摘@へ
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.
}
}
}
UPDATE
おかげで(This blog postがそれを記述する良い仕事をして、他のいくつかのを与えます良いヒント)、私は簡単な変更を加え、まだエラーを再現することができませんでした!
私が正しくあなたを理解していることを確認するには、要約すると、 'Read'との間に' SerialPort'内のデッドロックがあります'Close'コール? – chezy525
port_DataReceivedイベントハンドラでUI要素の更新を呼び出す方法を変更したり、BeginInvokeを使用してInvokeの代わりに更新したり、ソリューションの説明どおりに別のスレッドを使用してイベントを処理する必要があります。 – Afshin
UIのデータを別のスレッドで処理すると、問題が解決したようです。ありがとう! – chezy525