【发布时间】:2018-10-03 00:09:49
【问题描述】:
我正在使用后台工作程序读取值并将值传递给 Worker_ProgressChanged,以更新 UI。
在 Worker_DoWork 中:
while (agi.DvmReadyToRead) // wait for digipot to be adjusted before reading in worker
{
Thread.Sleep(20);
Application.DoEvents();
//logS.Debug("Waiting for ready to read in worker");
}
Thread.Sleep(40); // Give digipot chance to make the change
agi.SendSoftwareTriggerOne();
Thread.Sleep(7); // Duration for above command to execute
A = agi.ReadOne();
Thread.Sleep(1);
agi.InitOne();
Thread.Sleep(1);
sAndH3 = A[0];
worker.ReportProgress(0, new System.Tuple<double>(sAndH3));
agi.DvmReadyToRead = true;
在 Worker_ProgressChanged 中:
while (!agi.DvmReadyToRead)
{
//logS.Debug("waiting for ready to read in progress");
Thread.Sleep(0);
Thread.Sleep(0);
Thread.Sleep(0);
Thread.Sleep(0);
Thread.Sleep(0);
Application.DoEvents(); // Exception thown here
Thread.Sleep(1); // wait for DVM reading
}
agi.DvmReadyToRead = false;
// Then goes on to adjust output voltage up or down
第一次使用效果很好
Application.DoEvents();
然而,在第一次运行之后,此时我得到了一个 stackoverflow。在这里阅读了许多帖子后,DoEvents 并不是我想要实现的最佳方式。 所以我想要一种将布尔值传递回 DoWork 的方法,或者另一种允许工作人员能够读取 agi.DvmReadyToRead 布尔值的方法。
谢谢!
【问题讨论】:
-
这看起来像是一个非常失败的解决问题的尝试。但我不确定你的整体问题是什么——你目前向我们展示的只是你试图解决它。除了说我确定它不正确之外,我不确定要给出什么建议——因为我什至不确定
BackgroundWorker是否会成为正确解决方案的一部分,但这就是你真正向我们展示的全部内容。 -
@Damien_The_Unbeliever 感谢 cmets。 1)没有ProgressChanged中的DoEvents,DoWork看不到agi.DvmReadyToRead的状态,所以不测量电压并返回给Progress changed。 2)使用 DoEvents 会导致异常。 3)有什么比 DoEvents 更好地“释放”工人。 4)有没有办法将此 agi.DvmReadyToRead 布尔值传递给工作人员而不是全局变量。请问?
-
DoEvents 非常非常邪恶。使用 SOE 破坏程序的简单方法是允许 ProgressChanged 事件处理程序再次运行,甚至在之前的调用完成之前。再次调用 DoEvents,这允许再次调用 ProgressChanged,等等。你必须学会在没有它的情况下生活,这是没有必要的。
-
@HansPassant 谢谢,但是我可以用什么来代替 DoEvents 来“释放”工人呢?
-
我的水晶球很混浊,但它低声说这是一个单线程 COM 组件。它们无法在工作线程上正确运行。一个简单的解决方法是使用 Timer(工具箱中的那个)并轮询组件。一个实用的间隔值是 15,不能比这更快。没关系,您的 Sleep() 已经比这更长了。或者你需要创建一个适合这样一个组件的非工作线程,它必须调用Application.Run()。一个例子is here。先去找计时器。
标签: c# .net backgroundworker doevents