c++ - 关于windows窗体中多线程和后台工作线程的一些问题

标签 c++ winforms multithreading c++-cli backgroundworker

我遇到了使用 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/

相关文章:

c++ - 为什么我不能运行从源代码构建的 AssaultCube?

c# - 我如何在 dot net Core 中排列应用程序 dll 文件

c# - 在 .NET 中使用 volatile 进行线程间的单向通信

c# - Application.Exit() 与 Application.ExitThread() 与 Environment.Exit()

c++ - 我们可以使用构造函数和析构函数而不是设置和拆卸吗?

C++ 在类中包装 cin 和 cout - 重载 << 和 >> 运算符

c# - 如何在运行时修改 PropertyGrid(添加/删除属性和动态类型/枚举)

java - 了解 Java 线程中的等待

c++ - 我想仅使用递归将字符 "a"替换为字符 "z"

c# - 单击 "X"按钮时要求确认