2

我正在用 C# 开发一个应用程序,它从串行端口获取数据,处理它并将其显示给 UI。数据在 5-50 毫秒之间的速度非常快。在我没有使用任何线程之前。因此应用程序依赖于单个应用程序线程,该线程从串行端口获取数据,处理数据并将其显示给 UI。它正在丢失一些数据。然后我开始实现 BackgroundWorker 线程以消除单线程上的一些开销并考虑良好的性能。现在我得到“这个BackgroundWorker目前很忙,不能同时运行多个任务“错误。我认为线程无法应对来自串行端口的数据的速度。因此在执行“backgroundWorker1.RunWorkerAsync(data);”时抛出错误。我需要一些建议来实现这种更好的方法场景?

4

3 回答 3

2

geofftnz 是正确的,我会为你扩展一点。您应该只启动一次后台工作程序,并让它使用 ReportProgress 将数据反馈给 GUI 线程。工作线程看起来像这样。

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    BackgroundWorker worker = sender as BackGroundWorker;
    while(!e.CancellationPending)
    {
        ResultObject ro = new ResultObject();  // your own type here, obviously
        //Process and store some data in ro;
        worker.ReportProgress(0, ro);
        //Do not modify ro after reporting progress to avoid threading issues
    }
}

从 GUI 注册到 ProgressChanged 事件,并且只启动一次 worker。

于 2009-07-29T00:20:25.520 回答
0

问题是您在完成之前的操作之前调用了 backgroundWorker1.RunWorkerAsync() 。

您可能想要的是读取串行端口、缓冲数据并通知主 UI 线程数据可用的单线程。

于 2009-07-28T23:30:37.723 回答
0

尝试添加它,以确保后台工作人员一次只运行一项工作。

if(!backgroundWorker1.IsBusy)
    backgroundWorker1.RunWorkerAysnc();

您还可以取消当前作业,这是一个代码示例

    private void WhereBackworkerStarts()
    {
        backgroundWorker.WorkerSupportsCancellation = true;

        if (backgroundWorker.IsBusy)
            backgroundWorker.CancelAsync();
        else
            backgroundWorker.RunWorkerAsync();
    }

    // Events
    static void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        for(int i = 0; i < int.MaxValue; i++)
        {
            if (backgroundWorker.CancellationPending)
            {
                e.Cancel = true;
                return;
            }

            // Do work here
        }
        e.Result = MyResult;
    }

    static void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        // Deal with results
    }
于 2009-07-28T23:41:11.417 回答