我遇到了使用 C++ 在 Windows 窗体 GUI 应用程序中使用多线程的需要。从我对该主题的研究来看,后台工作线程似乎是实现我的目的的方法。根据示例代码我有
System::Void backgroundWorker1_DoWork(System::Object^ sender, System::ComponentModel::DoWorkEventArgs^ e)
{
BackgroundWorker^ worker = dynamic_cast<BackgroundWorker^>(sender);
e->Result = SomeCPUHungryFunction( safe_cast<Int32>(e->Argument), worker, e );
}
但是有一些事情我需要弄清楚并弄清楚
- 后台工作线程会让我的多线程生活变得更轻松吗?
- 为什么我需要电子->结果?
- 传递到backgroundWorker1_DoWork函数的参数有何用途?
- 参数 safe_cast(e->Argument) 的用途是什么?
- 我应该在 CPUHungryFunction() 中做什么?
- 如果我的 CPUHungryFunction() 有一个无限循环的 while 循环怎么办?
- 我可以控制工作线程获得的处理器时间吗?
- 能否更具体地控制设定时间内循环的次数?当我每秒只需要循环 30 次时,我不想每秒循环 1000 次,从而耗尽 CPU。 *是否有必要控制GUI更新的速度?
最佳答案
Will a background worker thread make my multithreading life easier?
是的,非常如此。它可以帮助您处理无法从工作线程更新 UI 的问题。特别是,ProgressChanged 事件可让您显示进度,而 RunWorkerCompleted 事件可让您使用工作线程的结果来更新 UI,而无需处理跨线程问题。
Why do I need e->Result?
将您所做工作的结果传回 UI 线程。您可以在 RunWorkerCompleted 事件处理程序 e->Result 属性中取回该值。然后您可以使用结果更新 UI。
What are the arguments passed into the function for?
告诉工作线程要做什么,这是可选的。否则与将参数传递给任何方法相同,只是更尴尬,因为您无法选择参数。例如,您通常会从 UI 传递某种值,如果需要传递多个值,请使用一个小帮助器类。总是倾向于这样做,而不是尝试在工作线程中获取 UI 值,那是非常麻烦的。
What things should I do in my CPUHungryFunction()?
当然会消耗 CPU 周期。或者通常做一些需要很长时间的事情,比如数据库查询。这不会消耗 CPU 周期,但需要很长时间才能让 UI 线程在等待结果时死亡。粗略地说,每当您需要执行超过一秒的操作时,您应该在工作线程而不是 UI 线程上执行它。
What if my CPUHungryFunction() has a while loop that loops indefinitely?
那么你的工作线程永远不会完成,也永远不会产生结果。这可能很有用,但并不常见。您通常不会为此使用 BGW,而只需使用 IsBackground 属性设置为 true 的常规线程。
Do I have control over the processor time my worker thread gets?
您可以通过调用 Thread.Sleep() 人为地减慢速度。这不是一件常见的事情,启动工作线程的目的是做工作。休眠的线程正在以非生产性的方式使用昂贵的资源。
Can more specifically control the number of times the loop loops within a set period? I don’t want to be using up cpu looping 1000s of times a second when I only need to loop 30 times a second.
和上面一样,你得 sleep 了。为此,请执行循环 30 次,然后休眠一秒钟。
Is it necessary to control the rate at which the GUI is updated?
是的,这非常重要。 ReportProgress() 可以是一个消防水带,每秒生成数千个 UI 更新。当 UI 线程无法跟上该速率时,您很容易遇到问题。您会注意到,UI 线程停止执行其常规职责,例如绘制 UI 和响应输入。因为它一直需要处理另一个调用请求来运行 ProgressChanged 事件处理程序。副作用是用户界面看起来卡住,您已经得到了您试图与工作人员解决的确切问题。它实际上并没有卡住,只是看起来那样,它仍在运行事件处理程序。但您的用户不会看到差异。
需要记住的一件事是 ReportProgress() 只需要让人眼满意即可。它无法看到每秒发生频率超过 20 次的更新。除此之外,它就变成了难以辨认的模糊。因此,不要把时间浪费在毫无用处的 UI 更新上。您也将自动避免消防水带问题。调整更新速率是您必须编程的事情,它不是内置于 BGW 中的。
关于c++ - 关于windows窗体中多线程和后台工作线程的一些问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14001298/