c#Serialport数据接收事件处理程序

时间:2017-07-07 10:38:54

标签: multithreading serial-port backgroundworker binaryreader binarywriter

我目前正在使用WPF从serialport读取数据。我能够从serialport&读取数据。使用Binarywriter将其写入File。

我现在面临的问题是: 我想分析这些数据。我开发了一个函数,其中包含用例结构来分割我在serialport datahandler中读取的数据。目的是分析捕获的数据。但我的程序只是从Serialport接收数据。它没有接近分析数据。

这是我从一些帖子中读到的几个选项,可能是我的问题的解决方案:

  • 背景工作者:如果是,那么我如何获取当前的程序?

  • 线程:我试了但是没用。我的程序正在递交文件和文件中的字节。不要开始我宣布的线程。

那么有人可以建议我一个更好的选择吗?

我的代码:

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();
}

2 个答案:

答案 0 :(得分:0)

我认为你应该运行设置IsBackground = true的线程; 我像那样使用它

new Thread(() =>
        {
            Thread.CurrentThread.IsBackground = true;
            //Do what you want to Run in background here
        }).Start();

或者简单的设置可以完成这项工作:

Analyser.IsBackground = true; Analyser.Start();

答案 1 :(得分:0)

修改 对于您的情况,不知道这是否是最佳方法,但这可能有效。

主线程中有一个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");
        }
    }
}

您可以在窗口中看到输出 - &gt;调试结果。

希望这有帮助。