2011-01-11 12 views
7

SynchronizationContext sınıfını öğreniyorum. Bir WinForm/WPF uygulaması bağlamında SynchronizationContext.SetSynchronizationContext()'u aramak için yaygın kullanım senaryolarının ne olduğunu anlamaya çalışıyorum. Bir iş parçacığının SynchronizationContext değerini ayarlamak ne demektir? Ne zaman yapmalıyım ve neden? Ayrıca, eğer ayarlarsam, bir noktada onu çözmemeli miyim?Bir UI uygulamasında SynchronizationContext.SetSynchronizationContext() ne zaman çağırılır?

Düzenleme: SetSynchronizationContext() düşündüğünü neden Cevaben

, @Hans Passant istedi. Sahip olduğum fikir, içeriği bir çalışan iş parçacığına ayarlamaktır, böylece bu iş parçacığı üzerinde çalışan kodun kullanılması için bir bağlam vardır.

private void button3_Click(object sender, EventArgs e) 
{ 
    var syncContext = SynchronizationContext.Current; 
    Task.Factory.StartNew(() => 
    { 
     // Setup the SynchronizationContext on this thread so 
     // that SomeAsyncComponentThatNeedsACurrentContext 
     // will have a context when it needs one 
     if (SynchronizationContext.Current == null) 
      SynchronizationContext.SetSynchronizationContext(syncContext); 

     var c = new SomeAsyncComponentThatNeedsACurrentContext(); 
     c.DoSomething(); 

    }); 
} 

cevap

12

Genel olarak bunu doğru şekilde ayarlamak için belirli bir UI sınıf kitaplığına bırakmanız gerekir. Winforms otomatik olarak bir WindowsFormsSynchronizationContext örneğini yükler, WPF bir DispatcherSynchronizationContext yükler, ASP.NET bir AspNetSynchronizationContext, bir Mağaza uygulaması WinRTSynchronizationContext, etcetera yükler. UI iş parçacığının olayları gönderdiği şekilde ayarlanan son derece özel eşitleme sağlayıcıları.

Bu uygulama ortamlarının ana iş parçacığı kullanma biçimleriyle ilgili özel bir şey var. Hepsi bir dağıtım döngüsü gerçekleştirir ve bildirimleri almak için iş parçacığı güvenli bir sıra kullanın. Genel olarak Windows GUI programlamasında "mesaj döngüsü" olarak bilinir. Bu, tüketiciyi uygulayan dağıtım döngüsü ile üretici/tüketici sorununa genel bir çözümdür.

Bir çalışan iş parçacığı için kendi eşitleme sağlayıcınızı oluşturmak, öncelikle böyle bir iş parçacığının aynı mekanizmayı uygulamasını gerektirir. Diğer bir deyişle, ConcurrentQueue gibi iş parçacığı için güvenli bir sıraya ihtiyacınız olacak ve sıradan gelen bildirimleri almak ve yürütmek için iş parçacığının yazılması gerekiyor. Temsilci bir nesne iyi bir seçim olurdu. Artık Post yöntemini uygulamakta sorun yaşamayacaksınız, sadece SendOrPostCallback temsilcisini sıraya ekleyin. Gönderme yöntemini uygulamak için fazladan iş gereklidir, iş parçacığı delegenin alındığına ve çalıştırıldığına işaret etmelidir. Dolayısıyla, sıra nesnesi de bir AutoResetEvent gerektirir.

Artık iş parçacığınızın genellikle yararlı bir iş parçacığı olmayı nasıl durduğunu unutmayın, bu bildirimleri göndermek zorunda kalmadan bataklık yaratır. Mevcut senkronizasyon sağlayıcıları zaten bunları nasıl yapıyor? Uygulamanız bir Winforms uygulamasıysa, çalışan iş parçacığınızda Application.Run() öğesini kukla görünmez bir formla da arayabilirsiniz. Ve senkronizasyon sağlayıcısını ücretsiz olarak otomatik olarak alırsınız.

+0

Kullanımının güncellenmemesi gerekir. – Sylvain

+0

güncellemem cevabınızı değiştiriyor mu? SynchronizationContext'i çalışan bir iş parçacığına ayarlamayı da düşünür müsünüz? – Sylvain

+0

Bunun hakkında ne düşündüğünü duymak isterim ... Teşekkürler – Sylvain

1

MSDN Dergisi'nin Şubat 2011 sayısında, bir Google makale tartışması SynchronizationContexts ve .NET evrenindeki çeşitli uygulamaları vardı.

http://msdn.microsoft.com/en-us/magazine/gg598924.aspx

Benim için gerçekten meselesi yüzünden karışıklık bazılarını açıkça yardımcı oldu. Genel olarak, Hans'ın dediği gibi, bir WinForms/WPF uygulamasında, SetSynchronizationContext()