.NET4.0和可怕的OnUserPreferenceChanged挂起en/prog/info/dotnet/MysteriousHang.html#BeginInvokeDance我刚回来并在最初遇到问题时发布了一个问题:又一个C#死锁调试问题我认为我已经通过删除UI线程构建的控件来解决它,但过了一会儿它又出现了(可能永远不会消失......)。我们一直在使用.NET3.5,据我所知是CLR2.0。最近,应用程序已升级为使用.NET4.0ClientProfile/CLR4.0。此外,我们已经从InfragisticsWinForms10.1升级到10.3。唯一的区别是以前的版本被混淆了……有没有人遇到混淆和挂起的问题?我一次又一次地尝试摆脱任何应用程序挂起,但不寻常的是,我无法在最新版本(使用.NET4.0)中重现挂起。使用IvanKrivyakov方便的Freezer应用程序(请参阅他的文章),可以根据请求触发WM_SETTINGCHANGE消息,可在以前的版本中重现(使用.NET3.5)。可能是我有点希望问题已经解决了,但是有人知道CLR从2.0到4.0的任何变化会导致这种情况发生吗?-----------解决方案--------------——————经过CLR2.0+Infragistics2010.1、CLR2.0+Infragistics2010.3、CLR4.0+Infragistics2010.1等程序变体后,我们相信我们已经确定问题出在WinForms2010.1中的Infragistics组件(没有修补程序)。我们仍然没有使用CLR2.0或CLR4.0使用Infragistics2010.3重现冻结(我们现在已经非常擅长重现这个......)。从UI线程构建的控件......是的,这是触发此问题的好方法。根本问题是由SystemEvents类引起的,该类具有在正确线程上引发事件的不可靠任务。UserPreferenceChanged事件是典型的麻烦制造者,许多控件都订阅它以便在用户更改桌面主题时它们可以重新绘制自己。组件供应商不会忽视对此的需求。工具箱中也没有标准的.NETFramework控件。通常测试此问题的好方法是锁定工作站(按Win+L键),这通常会触发用户计算机上的死锁。切换到安全桌面往往会触发事件。由于添加了怪癖,当您调试程序时,它永远不会发生,并且它具有棘手的与时间相关的行为,因为当机器上没有人时,这种情况往往会发生。特别难调试。像这样陷入麻烦的标准方法是由于程序中的初始化问题。订阅第一个SystemEvents事件会导致SystemEvents类自行初始化并设置接收这些通知和引发相应事件所需的管道。自定义初始屏幕(不只是显示位图)并在标记为STA的工作线程上运行足以导致此错误。像ProgressBar这样简单的东西就足够了。SystemEvents假定工作线程是程序的主线程,现在很容易在将来在错误的线程上生成事件。对此有一个很好的诊断,如果该工作线程不再存在,则会引发第一次机会异常。您可以在“输出”窗口中看到它。或者您创建另一个UI线程并在两个线程上都有表单。不可避免地,其中一种形式总是会在错误的线程上获取事件。唯一好的建议是承认在工作线程上创建UI是火箭科学,Microsoft不知道如何正确地做。值得注意的是.NET1.x控件有一个事件处理程序,当从错误的线程调用时它仍然可以正常工作,它只是调用Control.Invalidate()。然而,知识似乎在2.0已经丢失,ToolStrip就是一个很好的例子。并且不要相信组件供应商会这样做,尤其是Infragistics并没有很好的声誉。不要这样做。我找到的解决此问题的最佳指南是:它引导您使用WinDbg验证错误原因,并向您展示如何找到导致错误的原因。正如您所提到的,这很可能是因为控件是在非ui线程上创建的。在我的例子中,我通过创建一个使用UI线程中的SynchronizationContext来创建控件的工厂解决了这个问题,然后我调用了CreateControl()来强制创建UI句柄。Microsoft支持文章位于:如果您使用第一个CLR2.0然后使用CLR4.0从他的网页运行示例应用程序,您会注意到问题似乎在4.0中确实消失了-不确定发生了什么变化,但也许他们真的解决了问题。BR以上就是C#学习教程分享的全部内容:.NET4.0和可怕的OnUserPreferenceChangedHang。如果对大家有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
