2012-10-17 24 views
10

tüm kontrollerin ben aramak zorunda true döndüren bir InvokeRequired özelliği var. Değiştirmek amacıyla kumanda üzerindeki çağır [başlayın].Doğru kullanım Dispatcher.CheckAccess (veya atanmamış-kullanım)() Win yılında

WPF'de, DispatcherObject.CheckAccess() ve Dispatcher.CheckAccess()'da görünüşte benzer bir yapı var, ancak EditorBrowsable(EditorBrowsableState.Never) özniteliğinden korkuyorum. Editörün bu şekilde göz atmasını devre dışı bıraktığımda, "'u yapmamalısınız. Bunu gerçekten yapmalısınız. Gerekirse, acil sorununuzu çözmeniz gerekiyorsa, çözümünüzü sorunlu sorununuza yanlış şekilde tasarlamışsınızdır." Öte yandan, bulduğum tek alternatif (ve orijinal çözümüm) Thread.CurrentThread.ManagedThreadId == 1. (Bu korkunç. Ve ben biliyorum. O jenerik durumda çalışmaz. Bu benim sınırlı kullanımlar için çalışır, ama.)

MSDNdocumentationEditorBrowsable özelliğin arkasında varlığı ve mantığa sessizdir. Gerçekten de, “bunu kullanmama” anlamına geliyor mu, yazmış olsaydım ya da başka daha az yasaklayıcı bir anlamı var mı?

+0

MSFT'den birkaç kişi bu yayında yanıtlamış gibi görünüyordu. http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/bd0e6f6c-cadd-48f1-8e1a-163c2f17e4ca/ Seems 'EditorBrowsableState.Advanced' daha uygun olabilir, ancak görünmüyor neden çağrılmaması gerektiğine dair herhangi bir teknik neden (en azından o iş parçasından). – keyboardP

cevap

15

WPF, mevcut dişin bakılmaksızın Dispatcher.Invoke çağırabilir ve buna göre çağrıyı edeceğiz - Doğru iş parçacığı üzerinde zaten iseniz, sadece kodunuzu çağırmak olacak ve o işlemek için CheckAccess kullanır Bu davranış

Şu anda üzerinde bulunduğunuz konu BeginInvoke için konu dışıdır: BeginInvoke her zaman uyumsuzdur ve yürütme sırasını, dağıtıcının kuyruğuna eklediğiniz öğenin önceliğine bağlıdır.

Yöntemi hiç kullanmamanız gerekiyordu, halka açık olmaz: bu özniteliğin amacı yalnızca üyeyi Intellisense ve diğer editör tarayıcıları gibi mekanizmalardan gizlemektir. Genelde Dispatcher.CheckAccess()'u kullanmanız gerekmiyor, bu nedenle de neden göz atılabilir değil olarak işaretlenmiş olsa da, bunun bilgeliği sadece tahmin edebileceğimiz bir şeydir (Eric Lippert izliyorsa ;-)

Özet olarak: Dispatcher.Invoke'u arayın ve CheckAccess hakkında endişelenmeyin.

+2

Kullanacağını belirlemek için iş parçacığı erişimini denetlemenin haklı olduğunu düşünüyorum. CheckAccess'e dayanan açık kontrol veya belirli önkoşulların yapılması bazı durumlarda anlamlıdır. Ancak alışkanlık yapmak kötüdür, çünkü bu sadece çabaları kopyalamaktır. Yine de samimi bir şekilde konuşan Dispatcher.cs, gördüğüm en berbat .NET sınıflarından biridir. – erodewald

+0

Bunun tek dezavantajı, hangi yöntemlerin kullanıcı arabirimini güncelleyebileceğini ve her zaman endişelenmeden çalışacağını garanti eden bir yöntem içinde check/invoke etmenin aksine, onları çağırırken her zaman 'Invoke()' kullandığını hatırlamaya zorlandığınızdır. bu konuda – Basic

+0

Dan "Eğer zaten doğru iş parçacığınız varsa, sadece kodunuzu çağırır ve bu davranışı işlemek için CheckAccess kullanır" deyince doğru olduğunuzdan emin değilim. Dispatcher sınıfının kaynağına bakarsanız, DispatcherPriority (Gönderen Kişi) Gönderen ise yalnızca CheckAccess'i çağırır. IMO, size birim testi için yararlı olan Dispatcher için bir sarmalayıcı sınıf oluşturmak iyi bir fikirdir, ancak her Invoke çağrısı için kolayca CheckAccess ekleyebilirsiniz. Ana iş parçacığı gelen Dispatcher.Invoke çağrı geçmişte benim için bazı sorunlar var. – Zoman

0

ben eklersiniz: sen taklit eden istiyorsanız "If invokeRequired then ..."
söyleyebilirim: Ben

If Me.Dispatcher.Thread Is System.Threading.Thread.CurrentThread Then 
    Label1.Content = value 
Else 
    Me.Dispatcher.BeginInvoke(New Action(Of String)(AddressOf displaymessage), value) 
    Return 
End If 


sorunu: "if Dispatcher.CheckAccess" Bunun yerine, kullanımı kullanmayın CheckAccess ... çağırmak

Nevermind başlayacak hatta SONRA, her zaman doğru olmasıydı, aşağıdaki kodu da çalışıyor:

If Me.Dispatcher.CheckAccess Then 
    Label1.Content = value 
    Else 
    Me.Dispatcher.BeginInvoke(New Action(Of String)(AddressOf displaymessage), value) 
    Return 
End If