我刚刚重构了我的应用程序,从那以后我一直在使用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()
。
此外,我很欣赏有关如何追踪此错误的任何提示。我目前的方法是将输出添加到控制台并有选择地停用部分代码。
答案 0 :(得分:0)
我怀疑在某些情况下,您显示的代码会出现问题,因为InvokeRequired
位于IsHandleCreated
false
的情况下 - 即使您不在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" );
}
}