2015-09-17 9 views
6

मेरे पास एक डाटाग्रिड है, जो var Result_Full = new ObservableCollection<IP_DataRow>() से जुड़ा हुआ है। यह एक साधारण वर्ग है जिसमें कई स्ट्रिंग & डबल चर शामिल हैं। कुछ भी मुश्किल नहीं है।पृष्ठभूमि से पर्यवेक्षण चयन चयन करें

मैं क्या करता हूं, यह है कि मैंने एक एक्सेल फ़ाइल (टेलीरिक रेडस्प्रेडप्रोसेसिंग के साथ) पढ़ी है, जो मेरी कक्षा में पंक्तियों को पार करती है। मैं इसे धागे पर करता हूं ताकि यूआई अवरुद्ध न हो। मैं हालांकि कुछ समस्याओं का सामना करना पड़ा:

1) मैं एक लंबी प्रक्रिया है जो एक्सेल फ़ाइल पढ़ता है (में ref कीवर्ड का उपयोग नहीं कर सकते क्योंकि Result_Full एक सार्वजनिक संपत्ति एक डेटा ग्रिड के लिए बाध्य) है, लेकिन मैं, जहां अस्थायी ObservableCollection<IP_DataRow>() बनाने के लिए मूल्य रखा जाता है। एक बार प्रक्रिया समाप्त हो गया है मैं मान कॉपी करने के लिए निम्न स्क्रिप्ट चलाएँ:

 foreach (var item in tmpFull) 
     { 
      InvokeOnUIThread(() => 
      { 
       Result_Full.Add(item); 
      }); 
     } 

मैं करना चाहते हैं क्या, एक वास्तविक समय (यदि संभव हो) कैसे आइटम जोड़े जा रहे हैं में देखने के लिए सक्षम होने के लिए है मेरे डेटाग्रिड में संग्रह।

जैसा कि मैंने नेट 4.5 उपयोग कर रहा हूँ मैं BindingOperations.EnableCollectionSynchronization को लागू करने के रूप में कुछ अन्य डाक द्वारा सुझाव दिया गया था की कोशिश की, फिर भी मैं समझ नहीं सकता है एक प्रक्रिया में अस्थायी प्रयुक्त करने के लिए अपने यूआई bould संग्रह Result_Full बाध्य करने के लिए कैसे।

2) वर्तमान सेटअप के साथ भी, जब (मेरे यूआई के तहत) मैं अपने टैब पर जाता हूं जिसमें डेटाग्रिड होता है (मेरा डेटाग्रिड एक अलग टैबपेज पर है), और मैं उपर्युक्त के साथ संग्रह में नया आइटम जोड़ने का प्रयास करता हूं कोड, यह एक त्रुटि देता है: कॉलिंग थ्रेड इस ऑब्जेक्ट तक नहीं पहुंच सकता है क्योंकि एक अलग धागा इसका मालिक है।, जो कि अजीब है, InvokeOnUIThread कुछ और नहीं है लेकिन Dispatcher.Invoke() है, जो थ्रेड सुरक्षित होना चाहिए?

किसी भी मदद की अत्यधिक सराहना की जाएगी।

संपादित करें: दिखा रहा है और अधिक कोड:

इस प्रक्रिया मैं BackgroundWorker से कहते हैं:

public void ProcessFile() 
    { 
     var tmpError = new ObservableCollection<IP_DataRow>(); 
     var tmpFull = new ObservableCollection<IP_DataRow>(); 

     var _reader = new IP_ExcelReader(sExcelPath, ref tmpError, ref tmpFull); 
     string sResult = _reader.ReadExcelFile(); 
     if (sResult != string.Empty) 
     { 
      System.Windows.MessageBox.Show("Error processing selected Excel File!" + Environment.NewLine + Environment.NewLine + "Error message:" + Environment.NewLine + sResult); 
     } 

     foreach (var item in tmpError)//populates error list 
     { 
      IP_InvokeOnUIThread(() => 
      { 
       Result_Error.Add(item); 
      }); 
     } 

     foreach (var item in tmpFull)//populates full list 
     { 
      IP_InvokeOnUIThread(() => 
      { 
       Result_Full.Add(item); 
      }); 
     } 

     OnPropertyChanged("Result_Full"); 
     //OnPropertyChanged("Result_Error"); 

     iSelectedTabIndex = 1; 

    } 

यहाँ आप देख सकते हैं, मैं अस्थायी संग्रह बनाने होंगे tmpError, tmpFull मैं कहाँ इकट्ठा मेरी जानकारी। प्रक्रिया के अंत में, मैं मैन्युअल रूप से डेटाग्रिड से जुड़े अपने मुख्य संग्रह में मूल्यों की प्रतिलिपि बनाता हूं। मैं इसे बदलना चाहता हूं, जिसका अर्थ है कि प्रक्रिया के दौरान मूल्यों को मुख्य संग्रह (अस्थायी नहीं) पर कॉपी किया गया है, ताकि उपयोगकर्ता वास्तविक समय में संग्रह में मूल्यों को कैसे जोड़ा जा सके।

पीएस.2: मेरे लिए अज्ञात कारण के लिए, मेरी InvokeOnUIThread कॉल में झूठ बोलने वाली समस्याओं में से एक। एक बार जब मैं App.Current.Dispatcher.Invoke(action); से App.Current.Dispatcher.BeginInvoke(action);के साथ त्रुटि में बदल गया .. अलग-अलग धागे का स्वामित्व बंद हो गया।

+0

कौन सा धागा 'आइटम' और 'tmpFull' का मालिक किया जाता है 5 बार-बार कर रहे हैं? – Pieter21

+0

* कौन सा प्रेषक? * डिस्पैचर। वर्तमान टीएलएस में रखा जाता है, इसलिए प्रत्येक धागे का अपना प्रेषक होगा। आपको यूआई थ्रेड के प्रेषक तक पहुंचने की आवश्यकता है। – Will

+0

मैं ** App.Current.Dispatcher.Invoke (action) का उपयोग कर रहा हूं; **। हालांकि मैं यूआई प्रेषक है? मैं इसे तब कैसे एक्सेस करूं? –

उत्तर

5
  1. आप प्रगति की रिपोर्ट करने के लिए, थ्रेड के बजाय पृष्ठभूमिवर्कर का उपयोग कर सकते हैं। Here एक साधारण ट्यूटोरियल
  2. मेरा मानना ​​है कि बस डिस्पैचर को कॉल करने से संदर्भ के धागे का उपयोग किया जाएगा, जो आपके मामले में यूआई-थ्रेड नहीं है।Application.Current.Dispatcher बजाय

प्रयास करें संक्षेप में, मेरा मानना ​​है कि आप निम्न करना चाहिए:

  1. यूआई-सूत्र में सार्वजनिक ObservableCollection बनाएँ और डेटा ग्रिड
  2. को यह बाँध एक पृष्ठभूमि कार्यकर्ता बनाएँ। रिपोर्टिंग को सही पर सेट करें। ReportProgress और DoWork घटनाओं की सदस्यता लें।
  3. रन कार्यकर्ता async
  4. DoWork हैंडलर में एक सूची बनाएं और कुछ मूल्यों को पढ़ें। जैसे ही आप कुछ राशि तक पहुंचते हैं, आइए एक सौ कहें, (sender as BackgroundWorker).ReportProgress विधि पर कॉल करें, घटना में गुज़रने से यह संग्रह होता है कि आपने इस संग्रह को पॉप्युलेट किया है।
  5. रिपोर्ट प्रगति हैंडलर में, ईवेंट ऑब्जेक्ट्स के माध्यम से पारित सूची से अपने ऑब्जर्जेबल कोलेक्शन को पॉप्युलेट करें।
  6. कदम 4 - जब तक सब कुछ
+0

में फ़ोरैच कॉल निष्पादित किया गया है, मैं पहले ही पृष्ठभूमि कार्यकर्ता का उपयोग कर रहा हूं। मेरी समस्या यह है कि, मुझे नहीं पता कि मेरे अस्थायी संग्रह को डेटाग्रिड से संग्रहित संग्रह के साथ कैसे कनेक्ट किया जाए? इसका मतलब यह है कि, जब मैं अपना एक्सेल रीडिंग शून्य खत्म कर देता हूं, तो मैं केवल अपने मूल्यों को पॉप्युलेट कर रहा हूं। मैं अधिक कोड –

+0

साझा करूंगा, मैंने अपने एक्सेल रीडिंग फ़ंक्शन के लिए रेफरी पैरामीटर के रूप में पृष्ठभूमि वर्कर को पास कर दिया, और वहां मैंने प्रोसेस चेंज विधि कहा, जिसने चाल की! –

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