2010-11-02 19 views
9

Burada Ivan Krivyakov tarafından oldukça güzel refere ediyor korkulan OnUserPreferenceChanged Hang ile boğulmuş çok: Ben, bir süre önce yayınlanan bir soru .NET 4.0 ve korkunç OnUserPreferenceChanged asın

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

zaman başlangıçta sorunla karşılaştı:

Yet another C# Deadlock Debugging Question

ben UI iş parçacığı kapalı inşa edilmiş bir Kontrolü kaldırarak çözmüş düşündü, ama biraz whil sonra e yeniden ortaya çıktı (muhtemelen hiç gitmedi ...).

.NET 3.5 kullanan kullanıcılar CLR 2.0 kullanıyor. Son zamanlarda, uygulama .NET 4.0 İstemci Profili/CLR 4.0'ı kullanacak şekilde yükseltilmiştir. Ayrıca, Infragistics WinForms 10.1'den 10.3'e yükseltdik. Diğer tek fark ise, önceki versiyonun gizlenmesi ... ... kimsenin gizleme ve asma sorunları yaşadığını mı?

Herhangi bir uygulamadan kurtulmak için bir kez daha açtım ve her şey için, ama olağandışı bir şekilde, en son sürümde (.NET 4.0 kullanarak) askıda kalmayı başaramadım. Asın, önceki sürümde (.NET 3.5 kullanarak), Ivan Krivyakov'un kullanışlı Freezer uygulamasını (bunun için makalesine bakın) kullanarak çoğaltması kolaydır; bu istek üzerine bir WM_SETTINGCHANGE mesajı gönderir.

Bu sorunun kendiliğinden kendi kendine ortadan kalktığı konusunda küçük bir umutlu olabilirim, fakat CLR'de 2.0'dan 4.0'a herhangi bir değişiklik olup olmadığını bilen var mı?

--------------------------------------------- --------ÇÖZÜM----------------------------------------- Örneğin, uygulamanın varyasyonlarını test ettikten sonra, örn. CLR 2.0 + Infragistics 2010.1, CLR 2.0 + Infragistics 2010.3 ve CLR 4.0 + Infragistics 2010.1, sorunun WinForms 2010.1'deki bir Infragistics bileşeniyle ilgili bir sorun olduğunu belirlediğimize inanıyoruz (hot fixes yok). Yine de, CLG 2.0 veya CLR 4.0 ile Infragistics 2010.3'ü kullanarak donduruyoruz (ve bunu şimdi yeniden üretmekte oldukça iyiyiz ...).

+0

I. Krivyakov makalesi için yeni link: [Gizemli Hang] (http://www.ikriv.com/dev/dotnet/MysteriousHang.html) – tibx

cevap

15

UI iş parçacığı kapalı inşa edilmiş bir kontrol ...

Evet, bu bu sorunu tetiklemek için iyi bir yoldur

. Altta yatan problem, SystemEvents sınıfından kaynaklanır, olayları doğru iş parçacığı üzerinde yükseltmek için vazgeçilmez bir görevi vardır. UserPreferenceChanged olayı, tipik bir sorun yaratıcısıdır, kontrollerin birçoğu onu abone eder, böylece kullanıcılar masaüstü temasını değiştirdiğinde kendilerini yeniden boyayabilirler. Bir bileşen satıcısı bunun gerekliliğini göz ardı etmeyecekti. Araç kutusundaki standart .NET çerçeve denetimleri de.

Bu sorunu sınamak için genellikle iyi bir yöntem, iş istasyonunu kilitlemektir (Win + L tuşlarına basın), ayrıca kullanıcının kilidini genellikle kullanıcının makinesinde tetikleme yolu. Güvenli masaüstüne geçiş olayı tetikleme eğilimindedir. Bu, programınızı hata ayıkladığınızda ve bunun zamanla ilgili bir davranış sergilediği zaman, bunun hiç kimsenin makinede olmadığı zamanlarda gerçekleşme eğiliminde olduğundan dolayı gerçekleşmeyeceği gibi daha fazla sıkıntılarla. Hata ayıklaması çok zor.

Böyle bir sorunla karşılaşmanın standart bir yolu, programdaki başlatma sorunu nedeniyle gerçekleşir.Abone olunan ilk SystemEvents olayı, SystemEvents sınıfının kendisini başlatmasına ve bu bildirimleri almak ve ilgili olayı yükseltmek için gerekli olan sıhhi tesisatın kurulmasına neden olur. Çok fazla işleyen özel bir açılış ekranı (yani, yalnızca bir bitmap göstermekten daha fazlası) ve STA olarak işaretlenmiş bir çalışan iş parçacığı üzerinde çalışan bu yanlışı almak için yeterlidir. Bir ProgressBar kadar basit bir şey zaten yeterli. SystemEvents, çalışan iş parçacığının programın ana iş parçacığı olduğunu varsayar ve artık olayları gelecekte yanlış iş parçacığı üzerinde kolayca oluşturabilir. Bunun için iyi bir tanılama var, eğer o iş parçacığı artık etrafta değilse, o zaman ilk fırsat istisnası oluşturur. Çıktı penceresinde görebilirsiniz. Veya başka bir UI iş parçacığı oluşturursunuz ve her iki iş parçacığındaki formlarınız vardır. Kaçınılmaz olarak, bu formlardan biri, olayı yanlış iş parçacığına götürecektir.

Sadece iyi bir öneri, bir çalışan iş parçacığında kullanıcı arabirimi oluşturmanın Microsoft'un doğru bir şekilde nasıl yapılacağını bilmediği roket bilimi olduğunu kabul etmektir. .NET 1.x denetimleri, yanlış iş parçacığı çağrıldığında, düzgün çalışan bir olay işleyicisine sahip olduğundan emin olun, yalnızca Control.Invalidate() işlevini çağırır. Ama bu 2.0'da kaybolmuş gibi görünen bir bilgiydi, ToolStrip bir good example. Bu hakkı elde etmek için bir bileşen satıcısına güvenmeyin, özellikle Infragistics'in yıldız itibarı yoktur. Yapma.

+0

Serinletici bilgiler için teşekkürler, Hans! Herhangi bir çağrıyı pompaya verdiğimiz Application.Run() 'a ayrı bir çağrı ile oluşturulan bir Splash ekranımız var. Bu yanlış mı? Açılış ekranları için bazı yerleşik .NET desteği olduğunu bilmiyordum. Bir göz atacağım. – Roo

+0

Ayrıca, CLR 4.0 kullanan uygulamanın tanıtılmamış bir sürümünü kullanarak bu askıda bulunamadığımı herhangi bir fikriniz var mı? – Roo

+0

Kilitlenmeler, zamanlamaya * çok * duyarlıdır. Sürüm oluşturma işlemindeki zamanlama, hata ayıklama yapısıyla aynı olmaz. Bu sorunun neden olduğu konusunda çok fazla işiniz olduğu anlamına gelmiyor. Önerdiğim geçici çözümü öneriyorum. –

1

ben bu sorunu çözmek için bulduğum en iyi rehber burada:

Bu hatanın nedenini doğrulamak için WinDbg kullanarak gezinmenizi sağlar ve nasıl bulacağınızı göstermektedir ona ne sebep oluyor? Bahsettiğiniz gibi, büyük bir olasılıkla, olmayan bir iş parçacığı üzerinde oluşturulmuş bir denetim oluşuyordu.

Durumumda, denetimi oluşturmak için UI iş parçacığından SynchronizationContext kullanan bir fabrika oluşturarak sorunu çözdüm ve sonra bir UI tanıtıcısı oluşturulmasını zorlamak için CreateControl() öğesini çağırıyorum.

Microsoft Destek makale burada: o zaman CLR 4,0 birinci CLR 2.0 ve onun web sayfasından örnek uygulamasını çalıştırırsanız

0

o zaman sorun gerçekten görünüyor göreceksiniz 4.0'da gitmiş olmak - Neyin değiştiği hakkında bir fikriniz yok, ama belki de gerçekten problemi çözdüler. BR