我目前正在使用 WPF 从串行端口读取数据。我能够从串行端口读取数据并使用二进制写入器将其写入文件。
我现在面临的问题是: 我想分析这些数据。我开发了一个函数,其中包含用例结构来拆分我在串行端口数据处理程序中读取的数据。目的是分析捕获的数据。但是我的程序只是挂在从串行端口接收数据上。它没有接近分析数据。
这是我从一些帖子中读到的几个选项,可能是我问题的解决方案:
-
后台工作者:如果是,那么我如何在当前的程序中获取?
-
线程:我试过了,但它不起作用。我的程序正在将字节写入文件中,而不是向下启动我声明的线程。
那么有人可以建议我更好的选择吗?
我的代码:
private void port_DataReceived(Object sender, SerialDataReceivedEventArgs e) {
BinaryWriter writer=new BinaryWriter(File.Open("c:\temp\lbus2snifflog1.txt", FileMode.Append));
int bytes=comport.Read(buffer, 0, 4096);
for (int i=0;
i < bytes;
i++) {
//writer.Write(buffer, 0, bytes); // Write the data to the file on temp folder
data.Enqueue(buffer[i]); // Enqueue data from the buffer
writer.Write(buffer, 0, bytes);
}
//writer.Write(buffer, 0, bytes);
writer.Flush(); // Send all remaining data to the writer
writer.Close(); // Close the writer
/*Initilaise the Thread for the Analysis*/
Thread Analyser=new Thread(datacollection);
Analyser.Start();
}
我认为您应该使用设置 IsBackground = true 来运行线程; 我这样使用它
new Thread(() =>
{
Thread.CurrentThread.IsBackground = true;
//Do what you want to Run in background here
}).Start();
或者也许简单的设置就可以完成这项工作:
Analyser.IsBackground = true;
Analyser.Start();
编辑对于您的情况,不知道这是否是最佳方法,但这可能会起作用。
你在主线程中有一个 ConcurrentDictionary。在 BackgroundWorker 线程中,您可以从 ConcurrentDictionary 获取数据。然后,向主线程报告已处理的数据。
这是一个工作场景。
例:
class MyClass
{
private ConcurrentDictionary<int, string> serialPortsQueue =
new ConcurrentDictionary<int, string>();
private BackgroundWorker _worker;
public MyClass()
{
_worker = new BackgroundWorker()
{
WorkerSupportsCancellation = true,
WorkerReportsProgress = true
};
_worker.DoWork += DeviceDataAcquisition_DoWork;
_worker.ProgressChanged += DeviceDataAcquisition_ProgressChanged;
_worker.RunWorkerCompleted += DeviceDataAcquisition_RunWorkerCompleted;
_worker.RunWorkerAsync();
System.Diagnostics.Debug.WriteLine($"{DateTime.Now}: begin add first data");
serialPortsQueue.TryAdd(1, "data 1");
serialPortsQueue.TryAdd(2, "data 2");
serialPortsQueue.TryAdd(3, "data 3");
serialPortsQueue.TryAdd(4, "data 4");
serialPortsQueue.TryAdd(5, "data 5");
serialPortsQueue.TryAdd(6, "data 6");
serialPortsQueue.TryAdd(7, "data 7");
System.Diagnostics.Debug.WriteLine($"{DateTime.Now}: end add first data");
Thread.Sleep(2000);
System.Diagnostics.Debug.WriteLine($"{DateTime.Now}: begin add second data");
serialPortsQueue.TryAdd(8, "data 8");
System.Diagnostics.Debug.WriteLine($"{DateTime.Now}: end add second data");
}
private void DeviceDataAcquisition_DoWork(object sender, DoWorkEventArgs e)
{
// backgroundworker thread
if (sender is BackgroundWorker worker)
{
//just demo propose
int cnt = 0;
while (true)
{
if (worker.CancellationPending)
break;
if (serialPortsQueue.Count > 0)
{
KeyValuePair<int, string> kv = serialPortsQueue.ElementAt(0);
serialPortsQueue.TryRemove(kv.Key, out string value);
//just demo propose
// Simulate some processing
Thread.Sleep(1000);
worker.ReportProgress(0, kv);
//just demo propose
cnt++;
}
//just demo propose
if (cnt == 8)
break;
}
}
}
private void DeviceDataAcquisition_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// main thread
if (e.UserState is KeyValuePair<int, string> kv)
{
System.Diagnostics.Debug.WriteLine($"{DateTime.Now}: {kv.Key} -> {kv.Value}");
}
}
private void DeviceDataAcquisition_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (sender is BackgroundWorker worker)
{
worker.DoWork -= DeviceDataAcquisition_DoWork;
worker.ProgressChanged -= DeviceDataAcquisition_ProgressChanged;
worker.RunWorkerCompleted -= DeviceDataAcquisition_RunWorkerCompleted;
worker.Dispose(); // i think this does nothing...
System.Diagnostics.Debug.WriteLine($"{DateTime.Now}: end backgroundworker");
}
}
}
您可以在窗口中看到输出 ->调试结果。
希望这有帮助。