У меня есть некоторый код SerialPort, который постоянно должен считывать данные с последовательного интерфейса (например, COM1). Но, похоже, это сильно загружает процессор, и если пользователь перемещает окно или в него выводится много данных (например, байтов, полученных по последовательной линии), то связь нарушается.
Учитывая следующий код:
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);
}
Код необходимо собирать, так как поток данных постоянен
и данные должны быть проанализированы для (кадры / пакеты).
port = new SerialPort();
//Port configuration code here...
this.collector = dataCollector;
//Event handlers
port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
port.Open();
Если нет никакого взаимодействия с пользователем и ничего не добавляется в окно,
это работает нормально, но как только взаимодействие становится действительно запутанным.
Происходят тайм-ауты и т.д ....
Например, это все портит:
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);
});
Но даже простые вызовы log4net вызывают проблемы.
Существуют ли передовые практики для оптимизации связи SerialPort?
или кто-то может сказать мне, что я делаю не так ...
Обновление:
В случае, если вышеизложенное не имеет особого смысла. Я сделал очень простой (и глупый) маленький пример:
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);
}
}
Результат может выглядеть так:
Прослушивание на COM1: 6
Клиент на COM2: 10
Это пример данных, которые я отправляю
---> 6 Это пример данных, которые я отправляю
То есть чтение данных из порта происходит в главном потоке ....
Может ли это быть частью того, что вызывает мои проблемы?