应用程序仅在触发断点时挂起,.NET、C#、Visual Studio

本文关键字:NET Studio Visual 挂起 断点 应用程序 | 更新日期: 2023-09-27 18:19:34

我不久前重构了我的应用程序,从那以后,我一直在使用Visual Studio 2010进行调试时遇到问题。

我的应用程序按预期工作,而没有调试(没有遍历应用程序。附加的调试器不会引起任何问题)。然而,当断点被触发,我开始遍历应用程序时,Visual Studio和应用程序最多需要3-4步才能挂起
更强调这一点:无论我是从Visual Studio还是单机版启动它,只要不触发断点,它都能很好地与我的客户合作
我把断点放在代码的哪个位置并不重要。

IDE:Visual Studio 2010 x64
平台:.NET 4.0

重构包括许多对BeginInvoke的跨线程调用,所有调用都通过以下方法进行:

public static void BeginInvokeIfRequired(this Control control, Action action)
{
    if (control.InvokeRequired)
    {
        control.BeginInvoke(action);
    }
    else
    {
        action.Invoke();
    }
}

项目中没有一个对Control.Invoke()的调用。

  • 上面的方法有问题吗

此外,如果您能提供任何关于如何追踪这个bug的提示,我将不胜感激。我目前的方法是向控制台添加输出,并选择性地停用部分代码。

应用程序仅在触发断点时挂起,.NET、C#、Visual Studio

我怀疑在某些情况下,您显示的代码会带来问题,因为InvokeRequired存在于IsHandleCreatedfalse的情况下——即使您不在GUI线程上,它也会返回false。

参考请参见http://msdn.microsoft.com/en-us/library/system.windows.forms.control.invokerequired.aspx。

下面的代码抛出一个异常,而不是挂起。。。当没有遇到断点时,它"按预期工作"的事实可能是调试器在遇到断点时冻结所有线程的结果,这反过来可能导致不同的执行顺序等。

总之,这意味着:您的代码中可能有一些"竞赛条件",在新创建的控件上调用BeginInvokeIfRequired,然后该控件才有Handle。这甚至可以是你使用的一些第三方代码。。。

public static void BeginInvokeIfRequired(this Control control, Action action)
{
    if (control.IsHandleCreated)
    {
        if (control.InvokeRequired)
        {
            control.BeginInvoke(action);
        }
        else
        {
            action.Invoke();
        }
    }
    else { 
         // in this case InvokeRequired might lie ! 
         throw new Exception ( "InvokeRequired is possibly wrong in this case" );
         }
}