c#后台工作者数据无效-线程问题

本文关键字:线程 问题 无效 数据 后台 工作者 | 更新日期: 2023-09-27 17:54:45

请看看我的问题:

我开发的逻辑将在很长一段时间内运行。在运行逻辑时,我希望将状态报告给进度条。太棒了!所以我使用了background worker:

_backgroundWorker = new BackgroundWorker();
_backgroundWorker.DoWork += new DoWorkEventHandler(backgroundWorker_DoWork);
_backgroundWorker.ProgressChanged += new  ProgressChangedEventHandler(backgroundWorker_ProgressChanged);
_backgroundWorker.WorkerReportsProgress = true;
_backgroundWorker.RunWorkerAsync();

backgroundWorker_Dowork内,我有做这项工作的逻辑。我还声明了一个计时器,每隔50毫秒调用一次以报告状态。(在backgroundWorker_DoWork):

timer.Elapsed += (senderr, ee) => timer_Elapsed();
_timer.Interval = 50;

在timer_Elapsed中,我通过调用_backgroundWorker.ReportProgress(0)来更新UI控件;我没有在backgroundWorker_DoWork中调用ReportProgress的原因是,虽然我的代码需要一段时间,但我用来做我的工作的while循环非常快。如果我在while循环结束时调用reportprogress,则会出现相同的无响应类型的UI问题。

现在我的问题是当处理小数据时,当timer_Elapsed被调用时,所有变量和数据都是0和null。我似乎不明白为什么…我有丰富的多线程编程经验,但c#掩盖了一切,我不知道哪个线程有什么数据…

在长时间运行的逻辑完成后,计时器在backgroundWorker_DoWork中被处理。

知道为什么这些数据是无效的吗?

c#后台工作者数据无效-线程问题

您没有显示所有代码,但我对您描述的理解是timer.Elapsed运行在与后台工作线程不同的线程上,因此您有竞争条件。

另外,你关于"当处理少量数据时"的评论使我认为你的timer.Elapsed是在后台工作人员已经完成后调用的,并且你没有正确处理这种情况。

我建议你直接向后台工作人员报告进度。只是不要在循环的每次迭代中都使用,只使用千分之一(实际数字应该根据循环的旋转速度来选择)。

可以在while循环中这样做,但不能在每次迭代中都这样做。两个选择:

  1. 仅报告每n迭代的进度(例如每100迭代)
  2. 维护一个时间戳,当50ms过去时,报告状态并更新时间戳