Saya menggunakan Tasks untuk menjalankan panggilan server yang berjalan lama di ViewModel saya dan hasilnya akan kembali Dispatcher
digunakan TaskScheduler.FromSyncronizationContext()
. Sebagai contoh:
var context = TaskScheduler.FromCurrentSynchronizationContext();
this.Message = "Loading...";
Task task = Task.Factory.StartNew(() => { ... })
.ContinueWith(x => this.Message = "Completed"
, context);
Ini berfungsi dengan baik saat saya menjalankan aplikasi. Tetapi ketika saya menjalankan NUnit
pengujian saya, Resharper
saya mendapatkan pesan kesalahan pada panggilan ke FromCurrentSynchronizationContext
sebagai:
SynchronizationContext saat ini tidak dapat digunakan sebagai TaskScheduler.
Saya rasa ini karena tes dijalankan pada thread pekerja. Bagaimana cara memastikan pengujian dijalankan di utas utama? Saran lain dipersilahkan.
TaskScheduler.FromCurrentSynchronizationContext()
di dalam lambda dan eksekusi ditangguhkan ke utas lain. mendapatkan konteks di luar lambda memperbaiki masalah.Jawaban:
Anda perlu memberikan SynchronizationContext. Inilah cara saya menanganinya:
sumber
TestInitializeAttribute
, jika tidak hanya tes pertama yang lolos.Solusi Ritch Melton tidak berhasil untuk saya. Ini karena
TestInitialize
fungsi saya async, seperti pengujian saya, jadi dengan setiapawait
arusSynchronizationContext
hilang. Ini karena seperti yang ditunjukkan MSDN,SynchronizationContext
kelas ini "bodoh" dan hanya mengantri semua pekerjaan ke kumpulan utas.Apa yang berhasil bagi saya sebenarnya hanya melewatkan
FromCurrentSynchronizationContext
panggilan ketika tidak adaSynchronizationContext
(yaitu, jika konteks saat ini nol ). Jika tidak ada utas UI, saya tidak perlu menyinkronkannya sejak awal.Saya menemukan solusi ini lebih mudah daripada alternatifnya, yang mana:
TaskScheduler
ke ViewModel (melalui injeksi ketergantungan)SynchronizationContext
dan thread UI "palsu" untuk menjalankan pengujian - jauh lebih banyak masalah bagi saya yang layakSaya kehilangan beberapa nuansa threading, tetapi saya tidak secara eksplisit menguji bahwa callback OnPropertyChanged saya memicu pada utas tertentu jadi saya setuju dengan itu. Jawaban lain yang menggunakan
new SynchronizationContext()
tidak benar-benar lebih baik untuk tujuan itu.sumber
else
syncContextScheduler == null
[RequiresThread]
atribut.Saya telah menggabungkan beberapa solusi untuk mendapatkan jaminan untuk bekerja SynchronizationContext:
Pemakaian:
sumber