gpt4 book ai didi

c# - 关闭或隐藏表单会导致跨线程错误

转载 作者:太空狗 更新时间:2023-10-30 00:28:40 25 4
gpt4 key购买 nike

我对这个我一遍又一遍做的简单任务感到困惑。

我有一系列子表单。该数组在另一个表单的构造函数中启动:

frmChildren = new ChildGUI[20];

当用户请求查看子表单时,我会这样做:

if (frmChildren[nb] == null)
{
frmChildren[nb] = new ChildGUI();
frmChildren[nb].MdiParent = this.MdiParent;
}
frmChildren[nb].Show();

到目前为止这有效。在后台,我可以为这些表格下载新内容。下载完成后,我会触发 ChildChange 事件。这是它停止工作的地方。我只是想关闭/隐藏任何打开的表单,然后重新生成一组新的 -frmChildren = new ChildGUI[20];- 这是许多试验之一:

        for (int i = 0; i < frmChildren.Length;i++ )
{
if (frmChildren[i] != null)
{
//frmChildren[i].BeginInvoke(new EventHandler(delegate
//{
frmChildren[i].Close();
//}));
}
}
frmChildren= new ChildGUI[20];

我在 .Close() 上遇到跨线程异常。请注意,我已经尝试执行调用,但出于某种原因这样做会绕过 !=null。我认为这可能与垃圾收集器有关。有人有意见吗?

最佳答案

问题是您的匿名方法正在捕获 i - 所以当它在 UI 线程中被实际调用时,您有一个不同的 值>i,可以为空。试试这个:

for (int i = 0; i < frmChildren.Length; i++)
{
ChildGUI control = frmChildren[i];
if (control != null)
{
control.BeginInvoke(new EventHandler(delegate
{
control.Close();
}));
}
}
frmChildren = new ChildGUI[20];

参见 Eric Lippert's blog post为什么在循环中引入一个新变量可以解决这个问题。

编辑:如果你想使用 foreach 循环,它看起来像这样:

foreach (ChildGUI control in frmChildren)
{
// Create a "new" variable to be captured
ChildGUI copy = control;
if (copy != null)
{
copy.BeginInvoke(new EventHandler(delegate
{
copy.Close();
}));
}
}
frmChildren = new ChildGUI[20];

顺便说一句,您可以利用只想调用 void 方法这一事实来简化代码。由于这不再使用匿名方法,因此您可以取消“内部”变量:

foreach (ChildGUI control in frmChildren)
{
if (control != null)
{
control.BeginInvoke(new MethodInvoker(control.Close));
}
}
frmChildren = new ChildGUI[20];

关于c# - 关闭或隐藏表单会导致跨线程错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2284267/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com