2011-11-10 41 views
18

WPF dağıtıcı iş parçacığı nasıl kullanılır Bir görevde bir hizmet çağırır bir ViewModel kodu var. Görev bittiğinde, bir ObservableCollection doldurur. Sorun şu ki, devam etmek için görevini devam etmek için görevini devam etmesini ve görev zamanlayıcısı olarak TaskScheduler.FromCurrentSynchronizationContext öğesini sağlayarak, UI iş parçacığı üzerinde güncelleştirilir. TaskScheduler.FromCurrentSynchronizationContext - birim testi

Şimdiye kadar çok iyi, ama birim testine geldiğinde, "geçerli Senkronizasyonontnamesi bir TaskScheduler olarak kullanılamayabilir" diyerek bir istisna atar. Birim sınamada bir eşzamanlı SynchronizationContext kullanırsam, ObservableCollection dağıtım iş parçacığı tarafından güncelleştirilmekte olduğundan bir hata atar.

Bu konu üzerinde çalışmanın bir yolu var mı?

Teşekkürler.

cevap

17

Bu tam olarak kolay değil, ama bu gerçekten de zor değil. Yapmanız gereken şey, STA olarak ayarlanan bir çalışan iş parçacığı döndürmek ve üzerinde Dispatcher çalışma zamanını başlatmanızdır. Orada oturan bir işçiye sahip olduğunuz zaman, bu tür bir iş için başlangıçta başlatılmayan ünite test ipliklerinden iş yükleyebilirsiniz. Bu yüzden, önce burada test kurulumunda memuru iplik başlangıç ​​yapabilirsiniz:

this.dispatcherThread = new Thread(() => 
{ 
    // This is here just to force the dispatcher infrastructure to be setup on this thread 
    Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() => 
    { 
     Trace.WriteLine("Dispatcher worker thread started."); 
    })); 

    // Run the dispatcher so it starts processing the message loop 
    Dispatcher.Run(); 
}); 

this.dispatcherThread.SetApartmentState(ApartmentState.STA); 
this.dispatcherThread.IsBackground = true; 
this.dispatcherThread.Start(); 

Şimdi, temiz Yaptığın, sadece yapmak tavsiye Test temizleme, aşağıdaki şu konu kapatmaya istiyorsanız :

Dispatcher.FromThread(this.dispatcherThread).InvokeShutdown(); 

Yani, yoldan tüm bu altyapı şeyler, burada söz konusu iş parçacığı üzerinde yürütmek için test yapmanız gereken bu.

public void MyTestMethod 
{ 
    // Kick the test off on the dispatcher worker thread synchronously which will block until the work is competed 
    Dispatcher.FromThread(this.dispatcherThread).Invoke(new Action(() => 
    { 
     // FromCurrentSynchronizationContext will now resolve to the dispatcher thread here 
    })); 
} 
+1

Çalıştı, çok teşekkür ederim! – Alberto

14

bir bağlam oluşturmak için, test başlatma için bu ekleyin:

SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); 
+0

Evet, sorun çözüldü. Teşekkürler. –

0

Bu

TaskScheduler scheduler = Dispatcher.CurrentDispatcher.Invoke(TaskScheduler.FromCurrentSynchronizationContext) daha da basit

size kod sonra açıkça scheduler kullanabilirsiniz yapar (başlatıldı Çalışma sırasında TaskScheduler.FromCurrentSynchronizationContext() ile)