У меня есть программа, которая получает данные через uart и обрабатывает данные в двоичный файл. Мне нужно обрабатывать данные в отдельном потоке из-за требований времени. Я пытаюсь реализовать многопоточность / задачу, но я считаю, что я делаю не правильно. У меня есть отдельные классы: последовательный порт и форма1. Я ставлю в очередь данные, полученные в очереди списков, каждый список представляет собой пакет байтов, полученных через uart.
Следующий код показывает мой класс последовательного порта
public class FPGAPORT
{
int i = 0;
List<byte> data = new List<byte>();
public SerialPort PORT;
Queue<string> num_elements = new Queue<string>();
public ConcurrentQueue<List<byte>> msg = new ConcurrentQueue<List<byte>>() ;
CancellationTokenSource tokenSource1 = new CancellationTokenSource();
CancellationToken token1;
public FPGAPORT(string PortName, int BaudRate)
{
PORT = new SerialPort(PortName, BaudRate, Parity.None, 8, StopBits.One);
PORT.DiscardNull = false;
DataCollectionTimer.Elapsed += new ElapsedEventHandler(DataCollectionTimer_Tick);
DataCollectionTimer.Interval = 5000;
DataCollectionTimer.Enabled = false;
}
private void DataCollectionTimer_Tick(object sender, EventArgs e)
{
//logic for queuing the lists(packets of bytes)
if (queuing of one packet is done)
{
msg.Enqueue(data);
Task.Factory.StartNew(() => (System.Windows.Forms.Application.OpenForms["Form1"] as Form1).Data_collection(), token1, TaskCreationOptions.LongRunning, TaskScheduler.Default);
}
}
Это мой класс form1
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public void Data_collection()
{
if (FpgaDevice.msg.Count > 0)
{
List<byte> dequedData;
{
if (FpgaDevice.msg.TryDequeue(out dequedData))
{
crc(dequedData);
}
}
//logic for saving data into binary file
}
else{
// close port
}
}
public void crc(List<byte> data_packet)
{
//logic for calculating CRC on the list dequeued(one packet of
bytes)
}
}
Этот код работает, но он очень медленный, и я считаю, что это из-за таймера. Я попытался использовать событие получения последовательных данных, как показано ниже:
PORT.DataReceived += SerialPort_DataReceived;
private void SerialPort_DataReceived(object sender,
SerialDataReceivedEventArgs e)
{
//logic for queuing the lists(packets of bytes)
if (queuing of one packet is done)
{
msg.Enqueue(data);
Task.Factory.StartNew(() => (System.Windows.Forms.Application.OpenForms["Form1"] as Form1).Data_collection(), token1, TaskCreationOptions.LongRunning, TaskScheduler.Default);
}
}
Тем не менее, оно никогда не сработает, если у меня не будет точки разрыва с самого начала. Использование таймера было единственным способом заставить поток, полученный последовательными данными, выполнить. Логика CRC длинная, поэтому, вероятно, какой бы поток он ни использовал, он перегружает компьютер. Я честно не знаю, как это исправить. Это мой первый многопоточный проект. Я был бы очень признателен, если бы вы могли помочь или хотя бы указать мне верное направление или, возможно, сослаться на некоторые ссылки. Ниже я описал характеристики своего компьютера, если это влияло на скорость многопоточности. * Процессор: Процессор Intel Core i5-3570 третьего поколения (6 МБ, 3,4 ГГц) с графикой HD2500, Dell Optiplex 7010. Это четырехъядерный процессор. Жесткий диск: 2,5-дюймовый твердотельный накопитель на 500 ГБ, Optiplex MT Desktop