2011-11-10 14 views
18

पर WPF प्रेषक धागे का उपयोग कैसे करें मुझे एक ViewModel में कोड मिला है जो किसी कार्य के माध्यम से सेवा को कॉल करता है। जब कार्य समाप्त होता है, तो यह एक पर्यवेक्षण चयन को पॉप्युलेट करेगा। समस्या यह है कि यह ContinueWith विधि का उपयोग करके कार्य करने का कार्य कर रहा है और कार्य शेड्यूलर के रूप में TaskScheduler.FromCurrentSynchronizationContext प्रदान करता है, ताकि ओसी को यूआई थ्रेड पर अपडेट किया जा सके।TaskScheduler.FromCurrentSynchronizationContext - यूनिट परीक्षण

अब तक इतना अच्छा है, लेकिन जब यूनिट परीक्षण की बात आती है, तो यह एक अपवाद फेंकता है कि "वर्तमान सिंक्रनाइज़ेशन कॉन्टेक्स्ट को टास्कशेड्यूलर के रूप में उपयोग नहीं किया जा सकता है।" यदि मैं इकाई परीक्षण पर एक नकली सिंक्रनाइज़ेशन कॉन्टेक्स्ट का उपयोग करता हूं, तो ऑब्जर्वेबल कोलेक्शन एक त्रुटि फेंकता है क्योंकि इसे प्रेषक थ्रेड के आधार पर अपडेट किया जा रहा है।

वहाँ किसी भी तरह से इस के आसपास काम करने के लिए है?

धन्यवाद।

उत्तर

17

यह बिल्कुल आसान नहीं है, लेकिन यह वास्तव में मुश्किल नहीं है। आपको क्या करना है एक कार्यकर्ता थ्रेड को स्पिन करना जो एसटीए के रूप में सेटअप है और आप उस पर डिस्पैचर रनटाइम शुरू करते हैं। एक बार जब आप उस कर्मचारी को वहां बैठे हों तो आप इकाई परीक्षण धागे से काम भेज सकते हैं, जाहिर है, इस तरह के काम के लिए शुरू नहीं किया गया है। ,

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(); 

अब अगर आप सफाई से कि धागा निम्नलिखित अपने परीक्षण सफाई है, जो मैं सुझाव है कि आप करते हैं, तो आप बस कर में शट डाउन करना चाहते: तो, पहले, यहाँ कैसे आप अपने परीक्षण सेटअप में डिस्पैचर धागा प्रारंभ करेंगे तो है :

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

तो, रास्ते से बाहर है कि सभी बुनियादी सुविधाओं के सामान, यहाँ सब आपको लगता है कि धागे पर अमल करने के लिए अपने परीक्षण में क्या करने की जरूरत है।

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

यह काम किया, बहुत बहुत धन्यवाद! – Alberto

14

एक संदर्भ बनाने के लिए अपने परीक्षण initialisation को यह जोड़े,:

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

हां, इसने समस्या का समाधान किया। धन्यवाद। –

0

इस बनाता है यह और भी आसान

TaskScheduler scheduler = Dispatcher.CurrentDispatcher.Invoke(TaskScheduler.FromCurrentSynchronizationContext)

आप कोड तो scheduler स्पष्ट रूप से उपयोग कर सकते हैं (प्रारंभ रनटाइम के दौरान TaskScheduler.FromCurrentSynchronizationContext() के साथ)

संबंधित मुद्दे