Ich habe einen SerialPort-Code, der ständig Daten von einer seriellen Schnittstelle (zum Beispiel COM1) lesen muss. Dies scheint jedoch sehr CPU-intensiv zu sein und wenn der Benutzer das Fenster bewegt oder viele Daten im Fenster angezeigt werden (wie die Bytes, die über die serielle Leitung empfangen werden), wird die Kommunikation gestört.System.IO.Ports.SerialPort und Multithreading
Berücksichtigung der folgenden Code:
void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
byte[] buffer = new byte[port.ReadBufferSize];
var count = 0;
try
{
count = port.Read(buffer, 0, buffer.Length);
}
catch (Exception ex)
{
Console.Write(ex.ToString());
}
if (count == 0)
return;
//Pass the data to the IDataCollector, if response != null an entire frame has been received
var response = collector.Collect(buffer.GetSubByteArray(0, count));
if (response != null)
{
this.OnDataReceived(response);
}
Der Code muss gesammelt werden, da der Datenstrom, der konstant ist und die Daten hat für (Frames/Pakete) werden analysiert.
port = new SerialPort();
//Port configuration code here...
this.collector = dataCollector;
//Event handlers
port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
port.Open();
Wenn es keine Interaktion Benutzer ist und nichts zum Fenster hinzugefügt wird, dies funktioniert gut, aber sobald es Interaktion Kommunikation wirklich erhält, ist vermasselt. Timeouts auftreten etc ....
Zum Beispiel vermasselt dies alles auf:
Dispatcher.BeginInvoke(new Action(() =>
{
var builder = new StringBuilder();
foreach (var r in data)
{
builder.AppendFormat("0x{0:X} ", r);
}
builder.Append("\n\n");
txtHexDump.AppendText(builder.ToString());
txtHexDump.ScrollToEnd();
}),System.Windows.Threading.DispatcherPriority.ContextIdle);
});
Aber auch einfache Anrufe zu Problemen führen log4net.
Gibt es Best Practices Serialport Kommunikation oder kann mir jemand sagen, zu optimieren, was mache ich falsch ...
Update:
Wenn die oben nicht viel Sinn gemacht hat . Ich habe ein sehr einfaches (und dumm) kleines Beispiel:
class Program
{
static void Main(string[] args)
{
var server = new BackgroundWorker();
server.DoWork += new DoWorkEventHandler(server_DoWork);
server.RunWorkerAsync();
var port = new SerialPort();
port.PortName = "COM2";
port.Open();
string input = "";
Console.WriteLine("Client on COM2: {0}", Thread.CurrentThread.ManagedThreadId);
while (input != "/quit")
{
input = Console.ReadLine();
if (input != "/quit")
{
var data = ASCIIEncoding.ASCII.GetBytes(input);
port.Write(data, 0, data.Length);
}
}
port.Close();
port.Dispose();
}
static void server_DoWork(object sender, DoWorkEventArgs e)
{
Console.WriteLine("Listening on COM1: {0}", Thread.CurrentThread.ManagedThreadId);
var port = new SerialPort();
port.PortName = "COM1";
port.Open();
port.ReceivedBytesThreshold = 15;
port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
}
static void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
var port = (SerialPort)sender;
int count = 0;
byte[] buffer = new byte[port.ReadBufferSize];
count = ((SerialPort)sender).Read(buffer, 0, buffer.Length);
string echo = ASCIIEncoding.ASCII.GetString(buffer,0,count);
Console.WriteLine("-->{1} {0}", echo, Thread.CurrentThread.ManagedThreadId);
}
}
Das Ergebnis könnte wie folgt aussehen:
Zuhören auf COM1: 6 Client auf COM2: 10 Dies ist einige Beispieldaten, die ich sende ---> 6 Dies ist einige Beispieldaten, die ich
So liest die Daten aus dem Port senden auf dem Hauptthread passiert ....
könnte dieser Teil von dem, was meine Probleme verursacht?
Wo wird der letzte Codeabschnitt aufgerufen? Woher kommt die Variable "Daten"? –
Der obige Code wird aufgerufen, wenn der IDataCollector das Ereignis auslöst, um anzuzeigen, dass er einen vollständigen Datenrahmen erfasst hat. Es ist in dem WPF Windows. Aber selbst wenn Sie log.Warn (".....") Anweisungen im Code der IDataTransportServer oder IDataCollector Implementierungen hinzufügen, wird die SerialCommunication geschraubt ... Die 'Daten' sind einfach, was wir aus der Serie gelesen haben Zeile: puffer.GetSubByteArray (0, count) – TimothyP
Fast jeder Code wird dazu führen, dass die serielle Kommunikation schief geht ... – TimothyP