.NET 4.0和可怕的OnUser preferenceChanged航 [英] .NET 4.0 and the dreaded OnUserPreferenceChanged Hang

查看:432
本文介绍了.NET 4.0和可怕的OnUser preferenceChanged航的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在困扰着可怕的OnUser preferenceChanged航认为年代由伊万Krivyakov,这里refered到相当不错:

I have been plagued with the dreaded OnUserPreferenceChanged Hang that's refered to quite nicely by Ivan Krivyakov, here:

http://ikriv.com/en/prog/info/ DOTNET / MysteriousHang.html#BeginInvokeDance

我贴的问题而回,当我最初碰到的问题:

I posted a question a while back, when I originally encountered the problem:

还有一个C#调试死锁问题

我以为我已经通过删除构建关闭UI线程控制解决它,但一会儿后它再次出现(可能从来没有离开过......)。

I thought I had solved it by removing a Control that was constructed off the UI thread, but after a little while it reappeared (probably never left...).

我们一直在使用.NET 3.5,我的理解使用CLR 2.0。近日,applciation已经升级到使用.NET 4.0客户端配置文件/ CLR 4.0。此外,我们已经升级,从Infragistics的WinForms的10.1至10.3。其他唯一的区别是,previous版本进行模糊处理......有没有人经历了困惑和悬挂问题?

We've been using .NET 3.5, which I understand uses CLR 2.0. Recently, the applciation has been upgraded to use .NET 4.0 Client Profile / CLR 4.0. In addition, we've upgraded from Infragistics WinForms 10.1 to 10.3. The only other difference is that the previous version is obfuscated... has anyone experienced issues with obfuscation and hanging?

我有另外的刺在摆脱任何应用程序挂起一劳永逸,但与众不同的是,我一直无法(使用.NET 4.0),以重现挂在最新版本。窍门很简单,在previous版本重现(使用.net 3.5),采用伊万Krivyakov的方便冷冻应用程序(参见他的文章的话),应要求触发一个WM_SETTINGCHANGE消息。

I've had another stab at getting rid of any application hangs once and for all, but unusually, I have not been able to reproduce the hang in the most recent version (using .NET 4.0). The hang is simple to reproduce in the previous version (using .NET 3.5), using Ivan Krivyakov's handy Freezer application (see his article for it), which fires a WM_SETTINGCHANGE message upon request.

这可能是我是一个有点希望,这个问题已经消失了它自己的协议,但没有人知道是否有过任何改变,从2.0的CLR到4.0,将导致此?

It may be me being a little hopeful that the issue has disappeared off it's own accord, but does anyone know if there have been any changes to the CLR from 2.0 to 4.0 that would cause this?

-----------------------------------------------------SOLUTION--------------------------------------------------

因此​​,应用程序,例如测试变化后, CLR 2.0 + Infragistics的2010.1,CLR 2.0 + Infragistics的2010.3和CLR 4.0 + 2010.1 Infragistics的,我们相信我们已经发现的问题已是一个问题,在的WinForms 2010.1(无热修复)的Infragistics的组件。我们仍然还没有使用任何CLR 2.0或CLR 4.0 Infragistics的2010.3,而不是(我们已经得到了pretty的擅长,现在重现这个......)重现冻结。

So after testing variations of the application e.g. CLR 2.0 + Infragistics 2010.1, CLR 2.0 + Infragistics 2010.3 and CLR 4.0 + Infragistics 2010.1, we believe we've identified the problem to have been an issue with an Infragistics component in WinForms 2010.1 (no hot fixes). We still have yet to reproduce the freeze using either CLR 2.0 or CLR 4.0 with Infragistics 2010.3, instead (and we've gotten pretty good at reproducing this now...).

推荐答案

这是由于在程序初始化的问题。该订阅的第一SystemEvents事件导致SystemEvents类初始化本身和安装管道这是必要的,以接收这些事件。它创建一个隐藏的窗口,使得它可以接收通知消息,像WM_SETTINGCHANGE。你在你的表格所使用的控制往往订阅用户preferenceChanged事件,使他们能够重新绘制自己,当用户更改Windows主题或系统颜色。

It is caused by an initialization problem in your program. The very first SystemEvents event that is subscribed causes the SystemEvents class to initialize itself and setup the plumbing that's necessary to receive these events. It creates a hidden window so that it can receive the notification messages, like WM_SETTINGCHANGE. Controls you use in your forms often subscribe to the UserPreferenceChanged event so they can redraw themselves when the user changes the Windows theme or a system color.

这不顺心时的第一个控件是一个没有在主线程创建的。 SystemEvents注意到这一点,并创建一个辅助线程服务隐藏窗口。重要例如当一个控制台模式程序要使用这样的系统事件。从那里,订阅事件处理程序从辅助线程,而不是主线程提高。如果该事件处理程序,然后做一些与用户界面,死锁的可能性很高,窗户是不是线程安全的。您可以从调试+的Windows +线程窗口诊断这一点,你会看到助手线程名为.NET SystemEvents。

This goes wrong when that very first control is one that wasn't created on the main thread. SystemEvents notices this and creates a helper thread to service the hidden window. Important when for example a console mode program wants to use such a system event. From there on, the subscribed event handlers are raised from that helper thread instead of the main thread. If that event handler then does something with the UI, the likelihood for deadlock is high, windows are not thread-safe. You can diagnose this from the Debug + Windows + Threads window, you'll see that helper thread with the name ".NET SystemEvents".

这个问题的典型来源是一个自定义开机画面,在一个工作线程创建的,而主线程初始化自己。避免这一点,使用闪屏内置.NET支持。另一个原因是一个main()的入口点在你的程序,不具备[STAThread]属性。任何其他类型的code,在程序初始化时间开始工作线程,调用Application.Run()之前是一个潜在的麻烦制造者。

The typical source of this problem is a custom splash screen, created on a worker thread while the main thread initializes itself. Avoid this and use the built-in .NET support for splash screens. Another reason is a Main() entrypoint in your program that doesn't have the [STAThread] attribute. Any other kind of code that starts a worker thread at program initialization time, before calling Application.Run() is a potential troublemaker.

如果您有没有什么线索的code部分可能会做,那么你可以解决它通过在主订阅的​​虚拟系统事件()方法,确保隐藏的通知窗口总是在创造主UI线程。复制粘贴此code到主法,EnableVisualStyles调用后:

If you have no clue what part of the code might be doing this then you can work around it by subscribing a dummy system event in your Main() method, ensuring that the hidden notification window is always created on the main UI thread. Paste this code into your Main method, after the EnableVisualStyles call:

  Microsoft.Win32.SystemEvents.UserPreferenceChanged += delegate { };

这篇关于.NET 4.0和可怕的OnUser preferenceChanged航的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆