【问题标题】:Application hangs only when breakpoint is triggered, .NET, C#, Visual Studio应用程序仅在触发断点时挂起,.NET、C#、Visual Studio
【发布时间】:2016-05-12 08:19:05
【问题描述】:

不久前我重构了我的应用程序,从那时起我一直在使用 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()

  • 上面的方法有问题吗?

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

【问题讨论】:

  • 嘿,亚斯! :) 几乎可以肯定这个问题与多线程相关......您是否有任何可能导致循环死锁的线程等待/锁定内容?
  • @DarylTeo 在代码部分没有锁。唯一的 lock 语句在启动后立即执行
  • 多线程,编辑并继续。 ThreadPools 是一个奇迹(大部分时间)。有时,解决方案和代码的复杂性只会破坏视觉工作室。我注意到一些第三方组件只是破坏了这种代码,甚至可能是一些可重入代码破坏了调试器等。

标签: c# .net visual-studio debugging


【解决方案1】:

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

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

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

总而言之,这意味着:您的代码中可能存在一些“竞争条件”,其中在新创建的控件上调用BeginInvokeIfRequired,然后该控件具有Handle。这甚至可以是您使用的一些第 3 方代码...

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" );
         }
}

【讨论】:

  • 非常感谢您的回答。这仅适用于我在初始化后创建Control - 对吗?不幸的是,我没有在运行时创建任何控件(在InitializeComponents() 之后)。我只是改变了Visible 属性
  • @yas4891 不是真的,即使创建的控件也可能处于尚未创建 Handle 的状态......并且一些第 3 方库(过去例如 Infragen......)创建不可见内部使用的控制(如测量的东西)...
  • 我已将控制台输出添加到 BeginInvokeIfRequired 以防未创建句柄。我只在启动期间获得输出。我不使用第 3 方库(除非您将 MSChart 视为第 3 方库)
  • @yas4891 是的 - 在这种情况下,我认为 MSChart 是“第 3 方库”,因为它是执行的代码,您没有编写/无权访问。
猜你喜欢
  • 2011-01-12
  • 1970-01-01
  • 1970-01-01
  • 2021-12-16
  • 2021-07-12
  • 2022-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多