-2

我有一个 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 个标签和另一种形式(可选)。大多数时候它似乎工作正常,但偶尔会卡住。出于明显的原因,我无法在此处发布所有代码,而只是试图从我最怀疑的地方进行故障排除。

在此先感谢您的任何建议!

4

1 回答 1

-1

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

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

假设this指的是这两个标签的父类,我将修改您的代码如下:

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如果对象被释放,则返回 false,即使调用线程不是 UI 线程。

于 2017-04-10T18:18:06.453 回答