如何在C#中调用多个控件

How to Invoke multiple controls in C#

我有一个 C# 程序似乎在随机时间卡住,并在随机时间后自行恢复!当它卡住时,我可以看到内存增长,当它恢复时,内存使用率下降到正常水平。 CPU 用法似乎一直很正常,没有文件被写入或读取(按设计)。

程序调用外部(第 3 方)DLL 函数与硬件通信,并从 DLL 的回调 运行 在不同的线程上更新 UI。我检查了代码,发现除了以下代码(已编辑)外没有任何可疑之处:

private void Func(StructType para) {
    if (labelA.InvokeRequired) {
        labelA.BeginInvoke(new MethodInvoker(() => Func(para)));
        return;
    }
    if (labelB.InvokeRequired) {
        labelB.BeginInvoke(new MethodInvoker(() => Func(para)));
        return;
    }
    labelA.Text = para.A;
    labelB.Text = para.B;
}

我想知道这是否是从另一个线程更新 UI 元素的正确方法?如果没有,如何修改?

事实上,我调用了 6 个标签和另一个表单(可选)。它似乎在大多数时间都运行良好,但偶尔会卡住。出于明显的原因,我不能 post 此处的所有代码,但只是想从我最怀疑的地方进行故障排除。

提前感谢您的任何建议!

您无需单独检查每个控件以确定是否需要调用它 - 只有一个 UI 线程,因此该检查仅有用一次。请记住 - 修改任何 UI 组件几乎肯定会级联成一大堆其他 reads/writes 到其他 UI 组件;因此,你必须假设如果你正在触摸 any UI 对象,你必须假设你正在触摸 all UI 个组件。

考虑到这一点,我建议您执行一次调用检查,并且我建议对两个标签的父控件执行检查和调用。

假设 this 指的是 class,它是这两个标签的父级,我将按如下方式修改您的代码:

private void Func(StructType para) {
    if (this.InvokeRequired) {

        // Elide the explicit delegate declaration; it's not necessary.
        this.BeginInvoke( Func(para) );

        // Elide the return statement - multiple returns are messy, and in this case, easily removed.
    }
    else {
       labelA.Text = para.A;
       labelB.Text = para.B;
   }
}

请注意,如果对象被释放,InvokeRequired returns false,即使调用线程不是 UI 线程。