C# 表单调用导致奇怪的异常

C# 表单调用导致奇怪的异常,c#,.net,multithreading,forms,C#,.net,Multithreading,Forms,我在表单中有以下方法 public void Bye() { if (InvokeRequired && IsHandleCreated) { Invoke(new Action(Bye)); return; } Close(); } 此窗体是在主窗体的线程中创建的,但此方法是从System.Threading.Timer回调调用的。在调用Application.Run之前,将在Main方法中创建计时器

我在表单中有以下方法

public void Bye()
{
     if (InvokeRequired && IsHandleCreated)
     {
         Invoke(new Action(Bye));
         return;
     }
     Close();
}
此窗体是在主窗体的线程中创建的,但此方法是从
System.Threading.Timer
回调调用的。在调用Application.Run之前,将在Main方法中创建计时器

我的应用程序中有许多这样的表单,都使用了Bye方法。计时器每秒调用随机形式的Bye方法。 如果让应用程序运行几分钟,调用时会出现异常。 异常消息是

Invoke or BeginInvoke cannot be called on a control until the window handle has been created.
奇怪的是,当异常发生时,VisualStudio告诉我 invokererequired和IsHandleCreated都为false。在这种情况下,它怎么可能尝试调用Invoke呢? 我遗漏了什么?

更改顺序:

if (IsHandleCreated && InvokeRequired) 如果(IsHandleCreated&&InvokeRequired) 关于VS debugger:它可能会计算这两个属性以在监视窗口中显示它们的结果,此时它们可能返回false。

更改顺序:

if (IsHandleCreated && InvokeRequired) 如果(IsHandleCreated&&InvokeRequired)
关于VS debugger:它可能会计算这两个属性以在监视窗口中显示它们的结果,此时它们可能返回false。

Close()方法中有什么?@Tigran-这显然是框架提供的Form.Close()方法Close()方法中有什么?@Tigran-这显然是Form.Close()方法只有当IsHandleCreated返回true时,才会调用此版本InvokeRequired中的Framework提供的方法。实际上,这仍然不安全,因为此代码在其自己的线程中运行,并且在IsHandleCreated和InvokeRequired调用之间可能会销毁句柄。在没有其他信息的情况下,我建议您在调用时捕获适当的异常(但不要捕获异常,只捕获特定的异常类型)。@Tigran-这叫做短路。在使用&&的布尔测试情况下,如果第一项为false,则不会计算第二个条件。因此,如果没有窗口句柄,它将不会调用InvokeRequired。实际上,这并不能解决问题,IsHandleCreated在测试其值后的一纳秒内可能会变为false。卡布姆。或者调用请求就消失了。这是一场无法解决的线程竞赛。在允许窗体关闭之前停止线程。@Hans Passant-同意,这就是我添加有关异常的新注释的原因。此代码在计时器线程上下文中运行,因此这不是停止线程,而是必须停止计时器。但我不知道停止计时器后是否会出现最后一个计时器滴答声。在这个版本中,只有IsHandleCreated返回true时才会调用InvokeRequest。实际上,这仍然不安全,因为此代码在其自己的线程中运行,并且在IsHandleCreated和InvokeRequest调用之间可能会销毁句柄。在没有其他信息的情况下,我建议您在调用时捕获适当的异常(但不要捕获异常,只捕获特定的异常类型)。@Tigran-这叫做短路。在使用&&的布尔测试情况下,如果第一项为false,则不会计算第二个条件。因此,如果没有窗口句柄,它将不会调用InvokeRequired。实际上,这并不能解决问题,IsHandleCreated在测试其值后的一纳秒内可能会变为false。卡布姆。或者调用请求就消失了。这是一场无法解决的线程竞赛。在允许窗体关闭之前停止线程。@Hans Passant-同意,这就是我添加有关异常的新注释的原因。此代码在计时器线程上下文中运行,因此这不是停止线程,而是必须停止计时器。但我不知道最后一个计时器滴答声是否会在停止计时器后到达。