2011-12-15 20 views
6

WpF uygulamasında, viewmodel'de zaman harcayan bir işlem ayrı bir iş parçacığı kullanılarak çağrılır. Ancak bu işlev, görünümdeki nesnelere bağlı olan viewmodel'deki çeşitli özelliklere erişir. Onlara doğrudan erişmeyi denedim ve UI iş parçacığı tarafından sahip olunan hiçbir şikayetleri göremiyorum. Onları doğrudan dişler arasında kullanmanın sonuçlarını bilmek istiyorum.ViewModel özelliklerine ayrı iş parçacığından erişme

+0

Eğer 'ViewModel' değişen ya da sadece ayrı konuları okuyorsun? – SliverNinja

+0

sadece ayrı dişler – Aks

cevap

5

ViewModel'inizi okuma ve yazma da dahil olmak üzere herhangi bir iş parçacığından kullanmakta özgürsünüz. Bir ana istisna, koleksiyonlarla uğraşmaktır - ciltleme UI iş parçacığına otomatik olarak karar vermediğinden (basit bağlamalar gibi) veriye bağlı koleksiyonlar kullanıcı arabirimi iş parçacığına yazılmalıdır. Bununla birlikte, yine de herhangi bir yazım için uygun senkronizasyon gerçekleştirmeyi düşünmeniz gerekir. ViewModel başka bir sınıf olduğundan, normal iş parçacığı eşitleme sorunları ortaya çıkar.

Söyleniyor ki, tipik olarak, senkronizasyonu birçok durumda olduğundan biraz farklı bir şekilde ele almak isteyeceksiniz. WPF veri bağlamasının nesneleri kilitlememesi nedeniyle, kilitler genellikle bir ViewModel üzerinde çalışmaz. Bu nedenle, ViewModel'de eşitleme gerektiğinde, gerektiğinde kullanıcı arabirimi iş parçacığına geri aramaları için Dispatcher.Invoke/BeginInvoke numaralı telefonu kullanmanız gerekir. ama bu işte ObservableCollection genişletmek kullanırsanız

+0

Örneğin, sanal makinede "bool" a bağlı bir 'ToggleButton 'varsa. Ve ben ayrı bir iş parçacığında bir "if (bool)" yapıyorum, burada senkronizasyonu sürdürmek için ne yapmalıyım? Böylece, kullanıcı, geçişi ayarlayan ve koşulu yürütme koşulu arasında bir çakışma yoktur. – Aks

+0

@Aks Hayır. Böyle bir değeri okuyorsanız, hiç sorun yaşamayacaksınız. Bu söylendiği gibi, muhtemelen (teknik olarak) bool uçuculuğunu işaretlemelisiniz. Ayrıntılar için bkz .: http://stackoverflow.com/questions/458173/can-ac-sharp-thread-really-cache-a-value-and-ignore-changes-to-that-value-on-ot/458193 # 458193 –

1

Normal iş parçacığı güvenlik sorunlarınız dışında hiçbir sonuç yoktur. VM uygunluklarıyla genellikle problemli olan tek şey iplik afinitesi olan ObservableCollections'dur.

+0

Kilitleri gerçekten kullanacak olsaydım, muhtemelen UI iş parçacığı askıda kalmıyor mu? – Aks

+0

Bu doğrudur - ancak "olağan iş parçacığı güvenliği sorunları", WPF kullanmaya çalıştığınız tüm kilitleri veya standart iş parçacığı eşitlemelerini yok sayarken olağandışı çözümler gerektirme eğilimindedir. –

0

, ayrı bir iş parçacığı gelen güncelleyebilirsiniz:

/// <summary> 
/// Source: New Things I Learned 
/// Title: Have worker thread update ObservableCollection that is bound to a ListCollectionView 
/// http://geekswithblogs.net/NewThingsILearned/archive/2008/01/16/have-worker-thread-update-observablecollection-that-is-bound-to-a.aspx 
/// Note: Improved for clarity and the following of proper coding standards. 
/// </summary> 
/// <param name="e"></param> 
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e) 
{ 
    // Use BlockReentrancy 
    using (BlockReentrancy()) 
    { 
     var eventHandler = CollectionChanged; 

     // Only proceed if handler exists. 
     if (eventHandler != null) 
     { 
      Delegate[] delegates = eventHandler.GetInvocationList(); 

      // Walk thru invocation list 
      foreach (NotifyCollectionChangedEventHandler handler in delegates) 
      { 
       var currentDispatcher = handler.Target as DispatcherObject; 

       // If the subscriber is a DispatcherObject and different thread 
       if ((currentDispatcher != null) && 
        (currentDispatcher.CheckAccess() == false)) 
       { 
        // Invoke handler in the target dispatcher's thread 
        currentDispatcher.Dispatcher.Invoke(
         DispatcherPriority.DataBind, handler, this, e); 
       } 

       else 
       { 
        handler(this, e); 
       } 
      } 
     } 
    } 
} 

/// <summary> 
/// Overridden NotifyCollectionChangedEventHandler event. 
/// </summary> 
public override event NotifyCollectionChangedEventHandler CollectionChanged; 
İlgili konular