C# 在处理两个表单时,是否需要两个单独的InvokerRequired检查?

C# 在处理两个表单时,是否需要两个单独的InvokerRequired检查?,c#,winforms,multithreading,invoke,C#,Winforms,Multithreading,Invoke,给定 加载窗体与主窗体在同一线程上运行。上面看到的代码在单独的线程中运行。我怀疑我需要对主窗体进行另一次调用检查。我是否需要再次检查,或者我所拥有的是否安全?在尝试调用委托之前,如果表单未显示或已关闭,则应仅获取那些“未创建句柄”异常。但是,没有足够的代码来确定是否是这种情况,因此如果我处于您的位置,我会尝试在方法实际被调用之前确定是否正在调用加载表单的Closed事件 因为两个表单都在同一个线程上,所以只要检查加载表单的invokererequired属性就可以了。虽然一般来说,如果要在主窗体

给定

加载窗体与主窗体在同一线程上运行。上面看到的代码在单独的线程中运行。我怀疑我需要对主窗体进行另一次调用检查。我是否需要再次检查,或者我所拥有的是否安全?

在尝试调用委托之前,如果表单未显示或已关闭,则应仅获取那些“未创建句柄”异常。但是,没有足够的代码来确定是否是这种情况,因此如果我处于您的位置,我会尝试在方法实际被调用之前确定是否正在调用加载表单的
Closed
事件

因为两个表单都在同一个线程上,所以只要检查加载表单的
invokererequired
属性就可以了。虽然一般来说,如果要在主窗体上操作,应该检查该窗体的
invokererequired
属性。同样,如果要对加载表单进行操作(如上面调用
Close
),则应检查加载表单的
invokererequired
属性。上面您正在更改
panelOnMainForm
,因此我会检查它是否完全安全,但我认为这是没有必要的。

只有在尝试
调用
委托之前未显示或关闭表单时,才应该获得那些“未创建句柄”异常。但是,没有足够的代码来确定是否是这种情况,因此如果我处于您的位置,我会尝试在方法实际被调用之前确定是否正在调用加载表单的
Closed
事件

因为两个表单都在同一个线程上,所以只要检查加载表单的
invokererequired
属性就可以了。虽然一般来说,如果要在主窗体上操作,应该检查该窗体的
invokererequired
属性。同样,如果要对加载表单进行操作(如上面调用
Close
),则应检查加载表单的
invokererequired
属性。上面您正在更改主窗体上的
panelOnMainForm
,因此我会检查它是否完全安全,但我认为没有必要这样做

上面看到的代码在单独的线程中运行

当您知道代码运行在另一个线程上时,像这样使用invokererequired是一种错误的反模式。你可以用它做更多有用的事情。比如:

if(loadingForm.InvokeRequired)
   loadingForm.Invoke(closeLoadingAction);
else
   closeLoadingAction();
或者,如果您想在加载窗体的加载事件触发之前启动加载线程,则使用更实用的方法:

if (!loadingForm.InvokeRequired) {
    throw new InvalidOperationException("Threading race detected");
}
loadingForm.Invoke(closeLoadingAction);
或者用正确的方法,让表单的加载事件启动线程

上面看到的代码在单独的线程中运行

当您知道代码运行在另一个线程上时,像这样使用invokererequired是一种错误的反模式。你可以用它做更多有用的事情。比如:

if(loadingForm.InvokeRequired)
   loadingForm.Invoke(closeLoadingAction);
else
   closeLoadingAction();
或者,如果您想在加载窗体的加载事件触发之前启动加载线程,则使用更实用的方法:

if (!loadingForm.InvokeRequired) {
    throw new InvalidOperationException("Threading race detected");
}
loadingForm.Invoke(closeLoadingAction);

或者用正确的方法执行,让窗体的加载事件启动线程。

听起来像是为
loadingForm
创建的句柄与调用
loadingForm.Close()
之间的竞争

解决此问题的一种方法是启动包含
.Invoke
/
的线程。在触发
loadingForm.HandleCreated
事件时关闭
代码

while (!loadingForm.InvokeRequired) Thread.Sleep(50);
loadingForm.Invoke(closeLoadingAction);

听起来像是为
loadingForm
创建的句柄与调用
loadingForm.Close()
之间的竞争

解决此问题的一种方法是启动包含
.Invoke
/
的线程。在触发
loadingForm.HandleCreated
事件时关闭
代码

while (!loadingForm.InvokeRequired) Thread.Sleep(50);
loadingForm.Invoke(closeLoadingAction);

Handle
从何而来,此操作是否在控件内运行?控件是否已创建(具有可用句柄)?您还可以使用一种方便的扩展方法来减少表单控件上所需的
invokererequired
检查的冗长性,但这是另一回事。@QuintinRobinson-更新的问题。详细的东西会很好…我在我的代码中使用了很多次。WRT扩展方法:看看这个答案,如果你愿意但应该按原样工作,你可以将签名改为
Action
,而不是
MethodInvoker
。当你说“我怀疑我需要对主窗体的调用进行另一次检查”时你指的是具体的代码吗?除了检查主窗体的
Handle
属性(我假设是)之外,上面似乎没有任何内容涉及到主窗体。@PatrickQuirk-查看区域后的第一行
panelOnForm1.Controls.Add…
panelOnForm1是主窗体的成员。我可能应该把它命名为
panelOnMainForm
Handle
来自哪里,它是在控件中运行的吗?控件是否已创建(具有可用句柄)?您还可以使用一种方便的扩展方法来减少表单控件上所需的
invokererequired
检查的冗长性,但这是另一回事。@QuintinRobinson-更新的问题。详细的东西会很好…我在我的代码中使用了很多次。WRT扩展方法:看看这个答案,如果你愿意但应该按原样工作,你可以将签名改为
Action
,而不是
MethodInvoker
。当你说“我怀疑我需要对主窗体的调用进行另一次检查”时你指的是具体的代码吗?除了检查主窗体的
Handle
属性(我假设是)之外,上面似乎没有任何内容涉及到主窗体。@PatrickQuirk-查看区域后的第一行
panelOnForm1.Controls.Add…
panelOnForm1是主窗体的成员。我可能应该把它命名为
panelOnMainForm
。这个错误一定是由什么原因引起的。我没有关闭装货单。如果Mai