线程中的 UI 容器?

发布于 2024-12-10 21:44:23 字数 163 浏览 1 评论 0原文

代码中的兄弟。

我正在尝试使我的 WinForms 应用程序成为多线程。在我的后台工作人员的 DoWork 中,我有一个使用 MethodInvoker 委托更改一些控件的方法。我的问题是,每次我想从另一个线程更改每个控件时,是否都必须调用它,或者是否可以调用某种控件容器来避免多次调用某些控件?

brothers in code.

I'm trying to make my WinForms app multi threaded. In DoWork of my background worker I've got a method which changes few controls using MethodInvoker delegate. My question is if I have to invoke every control every time I want to change it from another thread or maybe there is some kind of container of controls which I can invoke to avoid multiple invoking certain controls?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

心如荒岛 2024-12-17 21:44:24

假设您想要更改两个 Label 上的文本。假设它们属于同一个 Form,您可以通过单独调用 Invoke...

void buttonInvoke_Click(object sender, EventArgs e) {
    Invoke((Action)(() => label1.Text = "A1"));
    Invoke((Action)(() => label2.Text = "A2"));
}

或通过分组到单个 Invoke< /code>,以节省一些打字并提高性能。

private void buttonInvoke_Click(object sender, EventArgs e) {
    Invoke(
        (Action)(() => {
            label1.Text = "B1";
            label2.Text = "B2";
        })
    );
}

Let's say you want to change the text on two Labels. Assuming they belong to the same Form, you can do this either by individual calls to Invoke...

void buttonInvoke_Click(object sender, EventArgs e) {
    Invoke((Action)(() => label1.Text = "A1"));
    Invoke((Action)(() => label2.Text = "A2"));
}

...or by grouping then in a single Invoke, to save some typing and increase performance.

private void buttonInvoke_Click(object sender, EventArgs e) {
    Invoke(
        (Action)(() => {
            label1.Text = "B1";
            label2.Text = "B2";
        })
    );
}
橘味果▽酱 2024-12-17 21:44:24

从技术上讲,您的所有 GUI 都是在主线程上创建的,因此,如果您调用 GUI 上的主面板,那么在该调用方法中,您可以在该方法中更改 GUI 上的其他控件,

另外,如果您的后台工作程序是在主线程上创建的然后您可以在主线程上调用报告进度事件...这意味着不需要调用。后台工作者的主要目的确实如此。

Technically all of your GUI is created on the main thread, so If you invoke say a main panel on the GUI then within that invocation method you can alter other controls on the GUI all within that method

Plus if your background worker was created on main thread then you can call report progress event back on main thread... Which means invocation not required. Main purpose of background workers really.

不气馁 2024-12-17 21:44:24
public void UpdateControl<T>(T control, Action<T> action) where T : Control
{
  if(control.InvokeRequired) 
    control.Invoke(() => action(control));
  else
    action(control);
}
public void UpdateControl<T>(T control, Action<T> action) where T : Control
{
  if(control.InvokeRequired) 
    control.Invoke(() => action(control));
  else
    action(control);
}
等数载,海棠开 2024-12-17 21:44:23

调用意味着安排您的代码在拥有控件的线程上运行,在所有简单的情况下,对于您的所有控件来说,该线程都将是同一个线程。因此,虽然每次想要与控件交互时都必须调用,但实际上您可以将任意数量的交互“池化”在一起,并且仅对整个部分调用一次(这样做会提高性能)。

如果你想“隐藏”调用,你必须编写一个类,当触发时,它会检测其属性的更改,并在与控件交互的代码上使用Invoke,其方式取决于这些属性。因此工作流程是:

  1. 您的工作人员修改“控制器”的属性,而不调用。这不会立即产生任何影响。
  2. 在某些时候,控制器被“触发”(也许由工作人员定期触发?)。
  3. 控制器检测(或已经知道)对其属性进行了哪些更改以及这些更改如何转换为调用控件上的代码。它调用与控件进行相应交互的代码块。

Invoking means scheduling your code to run on the thread that owns the controls, which in all straightforward cases would be the very same thread for all of your controls. So while you do have to invoke every time you want to interact with a control, you can in practice "pool" as many interactions as you wish together and only invoke once for the whole piece (doing so will be more performant).

If you want to "hide" the invocations you 'd have to write a class that, when triggered, would detect changes to its properties and use Invoke on code that interacts with your controls in a manner dependent on these properties. So the workflow would be:

  1. Your worker modifies the "controller"'s properties, without invoking. This does not have any immediate effect.
  2. At some point, the controller is "triggered" (perhaps periodically by the worker?).
  3. The controller detects (or already knows) what changes were made to its properties and how these translate to invoking code on controls. It invokes a block of code that interact with the controls accordingly.
十年不长 2024-12-17 21:44:23

我的问题是,每次我想从另一个控件更改它时,是否都必须调用每个控件
线程或者也许有某种控件容器,我可以调用它来避免多个
调用某些控件?

每次想要更改 UI 时都必须调用。调用操作不仅可以更改一个属性,还可以是更新 100 个控件的完整功能。

最小化调用有利于性能。

不,没有预定义的容器。假设您自己能够编程调用,例如匿名代码块。

My question is if I have to invoke every control every time I want to change it from another
thread or maybe there is some kind of container of controls which I can invoke to avoid multiple
invoking certain controls?

You have to invoke every time yiou want to change the UI. The invoke operation can do more than changing one peroeprty -it can be a complete function udpating 100 controls.

Minimizing invokes is good for performance.

No, there is no predefined container. You are assumed to be an able program an invoke, for example for an anonymous code block, yourself.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文