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