Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#ArgumentOutOfRange关闭表单时异常_C#_Winforms - Fatal编程技术网

C#ArgumentOutOfRange关闭表单时异常

C#ArgumentOutOfRange关闭表单时异常,c#,winforms,C#,Winforms,我正在写一个WinForms C程序 我正在尝试关闭除主窗体外的所有窗体,FrmMain 我必须隐藏我的主要形态 我通过打开两个表单生成了这个。一个是我的主窗体,另一个是另一个窗体,使用ShowDialog()方法显示 当在我的机器上执行此代码时,它似乎应该正确地关闭所有表单。出于某种原因,当我没有设置断点并运行这段特定的代码时,我会得到一个ArgumentOutOfRangeException,因为变量I到达了-1的位置。当我设置了断点,并慢慢地一步一步地完成每一段代码时,它工作得很好 for

我正在写一个WinForms C程序

我正在尝试关闭除主窗体外的所有窗体,
FrmMain

我必须隐藏我的主要形态

我通过打开两个表单生成了这个。一个是我的主窗体,另一个是另一个窗体,使用
ShowDialog()
方法显示

当在我的机器上执行此代码时,它似乎应该正确地关闭所有表单。出于某种原因,当我没有设置断点并运行这段特定的代码时,我会得到一个
ArgumentOutOfRangeException
,因为变量
I
到达了
-1
的位置。当我设置了断点,并慢慢地一步一步地完成每一段代码时,它工作得很好

for循环一直持续到
i
到达
-1
是没有意义的,因为我有
i>=0
条件

有人能给我解释一下为什么当我不使用断点时,
i
的索引会变为
-1
,而当我使用断点并逐个遍历循环的每一行时,索引会变为
0

如何解决这个问题

提前谢谢

            for (int i = Application.OpenForms.Count - 1; i >= 0; i--)
            {
                if (Application.OpenForms[i] is FrmMain)
                {
                    Application.OpenForms[i]?.BeginInvoke((MethodInvoker)delegate
                    {
                        Application.OpenForms[i]?.Hide();
                    });
                }
                else
                {
                    Application.OpenForms[i]?.BeginInvoke((MethodInvoker)delegate
                    {
                        Application.OpenForms[i]?.Dispose();
                    });
                }
            }
编辑:

防止获取ArgumentOutOfRangeException的方法是在for循环中添加另一个变量。 这是我更改的代码

            for (int i = Application.OpenForms.Count - 1; i >= 0; i--)
            {
                int i1 = i;
                if (Application.OpenForms[i] is FrmMain)
                {
                    Application.OpenForms[i]?.BeginInvoke((MethodInvoker)delegate
                    {
                        Application.OpenForms[i1]?.Hide();
                    });
                }
                else
                {
                    Application.OpenForms[i]?.BeginInvoke((MethodInvoker)delegate
                    {
                        Application.OpenForms[i1]?.Dispose();
                    });
                }
            }

本质上,
for
循环仅在条件为false时终止,这意味着
i
必须到达
-1
才能停止。看见 应该提供一个很好的解释

结合您正在使用的
BeginInvoke
,它本质上将执行移动到一个单独的线程(这意味着它的执行可能会延迟),并且
i
是一个捕获的变量,调用
Dispose()
时,
i
完全可能是
-1

当设置好断点后,主线程的执行速度可能会降低到所有独立线程都按预期顺序运行的程度,因此不会出现问题


您可以在此处找到捕获的变量:

搜索词“c#for closure”在何处、何时以及调用此代码多少次?@AfshinAghazadeh在新线程上的类中只调用一次需要注意的是,
BeginInvoke
在单独的线程上运行,所以完全有可能
i
Application.OpenForms[i]?.Dispose()的时候已经改变了时,您可能无法获得所需的行为。我认为“完全可能”在这里不够强。我想这是肯定的,谢谢。这帮了我的忙