如何在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 线程。
我有一个 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 线程。