2011-12-15 25 views
6

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

+0

आप 'ViewModel' बदलते रहे हैं या सिर्फ यह अलग धागे पढ़ने? – SliverNinja

+0

बस अलग थ्रेड – Aks

उत्तर

5

आप पढ़ने और लिखने सहित किसी भी धागे से अपने व्यूमोडेल का उपयोग करने के लिए स्वतंत्र हैं। एक मुख्य अपवाद संग्रह से निपट रहा है - डेटा बाध्य संग्रह उपयोगकर्ता इंटरफ़ेस थ्रेड पर लिखा जाना चाहिए, क्योंकि बाइंडिंग स्वचालित रूप से UI थ्रेड (जैसे कि सरल बाइंडिंग्स) पर मार्शल नहीं होती है।

हालांकि, आपको अभी भी किसी भी लिखने के लिए उचित सिंक्रनाइज़ेशन करने पर विचार करना चाहिए। सामान्य थ्रेड सिंक्रनाइज़ेशन समस्याएं घटित होंगी, क्योंकि व्यूमोडेल सिर्फ एक और वर्ग है।

कहा जा रहा है कि, आमतौर पर, आप कई मामलों में सिंक्रनाइज़ेशन को थोड़ा अलग तरीके से संभालना चाहते हैं। ताले आमतौर पर व्यूमोडेल पर काम नहीं करते हैं, क्योंकि डब्ल्यूपीएफ डेटा बाध्यकारी वस्तुओं को लॉक नहीं करेगा। इस प्रकार, आपको सामान्य रूप से Dispatcher.Invoke/BeginInvoke का उपयोग मार्शल कॉल को उपयोगकर्ता इंटरफ़ेस थ्रेड पर वापस करना चाहिए जब दृश्यमान में सिंक्रनाइज़ेशन की आवश्यकता होती है।

+0

उदाहरण के तौर पर, यदि मेरे पास वीएम में 'टॉगल बटन' को 'बूल' से बाध्य किया गया है। और मैं एक अलग थ्रेड में 'अगर (बूल)' कर रहा हूं, तो सिंक्रनाइज़ेशन को बनाए रखने के लिए मुझे क्या करना होगा ताकि उपयोगकर्ता टॉगल सेट करने और यदि स्थिति को निष्पादित करने के बीच कोई संघर्ष न हो। – Aks

+0

@Aks नंबर। यदि आप बस इस तरह के एक मूल्य पढ़ रहे हैं, तो आपको कोई समस्या नहीं होगी। कहा जा रहा है, आपको शायद (तकनीकी रूप से) बूल अस्थिर चिह्नित करना चाहिए। विवरण के लिए, देखें: http://stackoverflow.com/questions/458173/can-ac-sharp-thread-really-cache-a-value-and-ignore-changes-to-that-value-on-ot/458193 # 458,193 –

1

आपकी सामान्य थ्रेड सुरक्षा चिंताओं से अलग कोई परिणाम नहीं हैं। वीएम उचितताओं के साथ आमतौर पर समस्याग्रस्त एकमात्र चीज ObservableCollections है जिसमें थ्रेड एफ़िनिटी है।

+0

यदि मैं वास्तव में ताले का उपयोग करना चाहता था, तो क्या यह संभवतः यूआई थ्रेड लटका नहीं है? – Aks

+0

यह सच है - लेकिन "सामान्य थ्रेड सुरक्षा चिंताओं" को असामान्य कामकाज की आवश्यकता होती है, क्योंकि डब्ल्यूपीएफ किसी भी ताले या मानक थ्रेड सिंक्रनाइज़ेशन को अनदेखा कर देगा जिसे आप उपयोग करने का प्रयास करते हैं। –

0

आप इस के साथ अपने ObservableCollection का विस्तार उपयोग करते हैं, तो आपको एक अलग धागे से अद्यतन कर सकते हैं:

/// <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; 
संबंधित मुद्दे