मेरे पास एक विनफॉर्म प्रोग्राम है जो SerialPort
पर कुछ एसिंक्रोनस आईओ करता है। हालांकि, मैं नियमित रूप से SerialPort.Close() कॉल पर ठंडे प्रोग्राम के साथ किसी समस्या में चल रहा हूं, जो यादृच्छिक रूप से यादृच्छिक रूप से है।सी # WinialPort पर Winform ठंड।
मुझे लगता है कि यह एक थ्रेड सुरक्षा समस्या है, लेकिन मुझे यकीन नहीं है कि यह कैसे ठीक किया जाए। मैंने पोर्ट ओपन/क्लोज फ़ंक्शंस के साथ एसिंक डेटा रीसेस्ड हैंडलर को जोड़ने/हटाने और बंदरगाह पर इन और आउट बफर को हटाने का प्रयास किया, लेकिन ऐसा कुछ नहीं लगता है। मुझे लगता है कि महत्वपूर्ण SerialPort
कोड के नीचे है:
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.
}
}
}
अद्यतन
के लिए धन्यवाद @ Afrin के जवाब यूआई धागे से गतिरोध हालत (This blog post यह वर्णन एक अच्छा काम करता है, और कई अन्य देता है उनका कहना है अच्छी युक्तियाँ), मैंने एक साधारण परिवर्तन किया है, और अभी तक त्रुटि को पुन: उत्पन्न करने में सक्षम नहीं है!
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.
}
यकीन है कि मैं तुम्हें सही ढंग से समझ, सारांश में, वहाँ 'Read' और के बीच' SerialPort' के भीतर एक गतिरोध है बनाने के लिए 'बंद करें' कॉल? – chezy525
आप जिस तरह से आप port_DataReceived ईवेंट हैंडलर में यूआई तत्व अपडेट आह्वान बदलना होगा, BeginInvoke का उपयोग आह्वान के बजाय अद्यतन करने के लिए, या समाधान में वर्णित के रूप घटना को संभालने के लिए एक और धागा का उपयोग करें। – Afshin
किसी भिन्न थ्रेड पर UI के लिए डेटा को संभालने से समस्या हल हो गई है। धन्यवाद! – chezy525