11

मैं एक WP7 (विंडोज फोन 7) एप्लिकेशन बनाने के लिए एमवीवीएम लाइट का उपयोग कर रहा हूं। मैं पृष्ठभूमि थ्रेड पर चलाने के लिए मॉडल द्वारा किए गए सभी काम करना चाहता हूं। फिर, जब काम पूरा हो जाता है, तो एक ईवेंट बढ़ाएं ताकि ViewModel डेटा को संसाधित कर सके।विंडोज फोन 7 के लिए पृष्ठभूमि थ्रेड पर फ़ंक्शन कैसे चलाएं?

मुझे पहले ही पता चला है कि मैं एक WP7 ऐप से असीमित रूप से एक प्रतिनिधि को नहीं बुला सकता हूं।

वर्तमान में मैं ThreadPool.QueueUserWorkItem() का उपयोग करने के लिए एक पृष्ठभूमि धागे पर कुछ कोड को चलाने और MVVM लाइट के DispatcherHelper.CheckBeginInvodeOnUI() का उपयोग करने के यूआई धागे पर एक घटना को बढ़ाने के लिए ViewModel संकेत देने के लिए कि डेटा लोड किया गया है कोशिश कर रहा हूँ (जब वे डिज़ाइन-टाइम व्यू प्रदर्शित करने का प्रयास करते हैं तो यह VS2010 और ब्लेंड 4 को क्रैश करता है)।

क्या पृष्ठभूमि थ्रेड पर कुछ कोड चलाने के लिए कोई नमूना कोड है और फिर एक WP7 ऐप के लिए UI थ्रेड पर किसी ईवेंट को प्रेषित करें?

अग्रिम धन्यवाद, जेफ़।

संपादित करें - यहां एक नमूना मॉडल

public class DataModel 
{ 
    public event EventHandler<DataLoadingEventArgs> DataLoadingComplete; 
    public event EventHandler<DataLoadingErrorEventArgs> DataLoadingError; 
    List<Data> _dataCasch = new List<Data>(); 

    public void GetData() 
    { 
     ThreadPool.QueueUserWorkItem(func => 
     { 
      try 
      { 
       LoadData(); 
       if (DataLoadingComplete != null) 
       { 
        //Dispatch complete event back to the UI thread 
        DispatcherHelper.CheckBeginInvokeOnUI(() => 
        { 
         //raise event 
         DataLoadingComplete(this, new DataLoadingEventArgs(_dataCasch)); 
        }); 
       } 
      } 
      catch (Exception ex) 
      { 
       if (DataLoadingError != null) 
       { 
        //Dispatch error event back to the UI thread 
        DispatcherHelper.CheckBeginInvokeOnUI(() => 
        { 
         //raise error 
         DataLoadingError(this, new DataLoadingErrorEventArgs(ex)); 
        }); 
       } 
      } 
     }); 
    } 

    private void LoadData() 
    { 
     //Do work to load data.... 
    } 
} 

उत्तर

16

यहां बताया गया है कि मैं इसका समाधान कैसे करूंगा।

आपका व्यूमोडेल लागू करता है INotifyProperty सही किया गया है? घटनाओं को प्रेषित करने की कोई आवश्यकता नहीं है। मॉडल में उन्हें "बेयर" उठाएं, फिर व्यूमोडेल में उठाए गए RaiseProperty को प्रेषित करें।

और हां, आपके पास अपने कोड में कुछ प्रकार के सिंगलटन मॉडल/डेटाबेस होना चाहिए। आखिरकार, कुछ विशाल सिंगलटन नहीं होने पर एसक्यूएल डाटाबेस क्या है? चूंकि हमारे पास WP7 में डेटाबेस नहीं है, इसलिए एक सिंगलटन ऑब्जेक्ट बनाने में शर्मिंदा न हों। मेरे पास "डेटाबेस" नामक एक है :)

मैंने अभी वहां अपने डाटलोड्स को थ्रेड करने का प्रयास किया है, और महसूस किया है कि वास्तव में सबसे अच्छा तरीका केवल मॉडल स्तर पर इंगित करने के लिए INotifyProperty को कार्यान्वित कर रहा है। There's no shame in this

तो यह दिया गया है कि, मैं सिंगलटन डेटाबेस ऑब्जेक्ट में अपनी टूर्स "टेबल" लोड करने और वापस करने के लिए क्या कर रहा हूं (थ्रेड स्लीप को नोट करने के लिए इसे थोड़े समय तक लोड करने के लिए नोट करें, आमतौर पर इसके उप 100ms)। डाटाबेस क्लास अब INotifyPropertyChanged लागू करता है, और लोड होने पर ईवेंट बढ़ाता है:

public ObservableCollection<Tour> Tours 
{ 
    get 
    { 
    if (_tours == null) 
    { 
     _tours = new ObservableCollection<Tour>(); 
     ThreadPool.QueueUserWorkItem(LoadTours); 
    } 
    return _tours; 
    } 
} 

private void LoadTours(object o) 
{ 
    var start = DateTime.Now; 
    //simlate lots of work 
    Thread.Sleep(5000); 
    _tours = IsoStore.Deserialize<ObservableCollection<Tour>>(ToursFilename) ?? new ObservableCollection<Tour>(); 
    Debug.WriteLine("Deserialize time: " + DateTime.Now.Subtract(start).ToString()); 
    RaisePropertyChanged("Tours"); 
} 

आप फ़ॉलो करते हैं? मैं पृष्ठभूमि धागे पर टूर सूची को deserializing कर रहा हूँ, फिर एक संपत्ति बदलती घटना उठा रहा हूँ।

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

हुक ViewModel के निर्माता में डाटाबेस घटना:

public TourViewModel() 
{ 
Database.Instance.PropertyChanged += DatabasePropertyChanged; 
} 

उपयुक्त तालिका बदलाव के लिए सुनो (! हम जादू तार प्यार ;-)):

private void DatabasePropertyChanged(object sender, PropertyChangedEventArgs e) 
{ 
    if(e.PropertyName == "Tours") 
    { 
    LoadTourList(); 
    } 
} 

रिकॉर्ड मैं से चाहते हैं उसे चुनें तालिका, फिर दृश्य को बताएं कि नया डेटा है:

public void LoadTourList() 
{ 
    AllTours = (from t in Database.Instance.Tours 
    select new TourViewModel(t)).ToList(); 

    RaisePropertyChanged("AllTours"); 
} 

और आखिरकार, आपके व्यूमोड में elbase, यह जांचना सबसे अच्छा है कि क्या आपके RaisePropertyChanged को प्रेषण की आवश्यकता है या नहीं। मेरे "SafeDispatch" विधि काफी MVVMlight से एक के रूप में एक ही है:

private void RaisePropertyChanged(string property) 
{ 
    if (PropertyChanged != null) 
    { 
    UiHelper.SafeDispatch(() => 
     PropertyChanged(this, new PropertyChangedEventArgs(property))); 
    } 
} 

यह मेरा कोड में पूरी तरह से काम करता है, और मुझे लगता है कि काफी साफ है?

आखिरकार, विशेषज्ञों के लिए अतिरिक्त: WP7 में, IsIndeterminate = अपने पृष्ठ पर सही के साथ प्रोग्रेसबार जोड़ने के लिए अच्छा हो सकता है - यह "बिंदीदार" प्रगति पट्टी प्रदर्शित करेगा। फिर आप क्या कर सकते हैं जब व्यूमोडेल पहली बार लोड होता है तो आप दृश्यमान ("संबंधित प्रॉपर्टी चेंज इवेंट) को" प्रोग्रेसबर्विज़िबल "प्रॉपर्टी सेट कर सकते हैं। इस ViewModel संपत्ति के लिए प्रोग्रेसबार की दृश्यता को बाध्य करें। जब डेटाबेस प्रॉपर्टी चेंजेड इवेंट आग लगती है, तो प्रोग्रेसबार को दूर करने के लिए दृश्यता को सेट करने के लिए सेट करें।

इस तरह उपयोगकर्ता deserialization चल रहा है, जबकि उनकी स्क्रीन के शीर्ष पर "IsIndeterminate" प्रगति पट्टी देखेंगे। अच्छा!

+0

प्रदर्शन प्रभावों को दोबारा जांचना न भूलें अनिश्चित प्रगति सलाखों का उपयोग करने के लिए: http://www.jeff.wilcox.name/2010/08/progressbarperftips2/ –

+0

निश्चित रूप से IsDeterminte = गलत जब भी दिखाई नहीं दे रहा है सेट करें। – Micah

+0

सुरक्षित डिस्प्ले का स्रोत अच्छा होगा। – Sam

0

मैंने पहले WP7 के लिए विकास नहीं किया है, लेकिन मैं this article that might be useful पाया है!

public DinnersViewModel(IDinnerCatalog catalog) 
{ 
    theCatalog = catalog; 
    theCatalog.DinnerLoadingComplete += 
     new EventHandler<DinnerLoadingEventArgs>(
       Dinners_DinnerLoadingComplete); 
} 

public void LoadDinners() 
{ 
    theCatalog.GetDinners(); 
} 

void Dinners_DinnerLoadingComplete(
    object sender, DinnerLoadingEventArgs e) 
{ 
    // Fire Event on UI Thread 
    View.Dispatcher.BeginInvoke(() => 
     { 
      // Clear the list 
      theDinners.Clear(); 

      // Add the new Dinners 
      foreach (Dinner d in e.Results) 
       theDinners.Add(d); 

      if (LoadComplete != null) 
       LoadComplete(this, null); 
     }); 
} 

मुझे आशा है कि यह उपयोगी है :):

यहाँ है कि आप कैसे एक और धागे से यूआई के लिए एक घटना को बढ़ाने के लिए पर एक अच्छा विचार देना चाहिए लेख से डाइनिंग दार्शनिक नमूना कोड है।

एक बात जो उलझन में है: आपने कहा कि जब आप ईवेंट को बढ़ाने के लिए सहायक का उपयोग करते हैं, तो वीएस -2010 क्रैश हो जाता है ... जब आप क्रैश हो रहे हैं तो आप वास्तव में क्या देख रहे हैं? क्या आपको अपवाद मिल रहा है?

+0

मुझे आपके द्वारा संदर्भित स्रोत कोड खोजने में परेशानी हो रही है, क्या आपके पास कोई लिंक है? मुझे यह देखना दिलचस्प है कि कैसेatalog.GetDinners() लागू किया गया है। –

+0

@ जेफ, यह मेरे द्वारा लिंक किए गए आलेख में है (मेरे उत्तर की पहली वाक्य), यहां उस आलेख का यूआरएल है: http://chriskoenig.net/series/wp7/ – Kiril

0

जेफ, मैं अभी भी यह सामान खुद को समझ रहा हूं। मैंने एक समान प्रश्न पोस्ट किया और एक सरल नमूना बनाकर इसे स्वयं जवाब दिया। यहाँ:

A super-simple MVVM-Light WP7 sample?

सार है:

1) मैं ViewModelBase से मेरे मॉडल (हाँ अपने मॉडल) व्युत्पन्न। यह मुझे संदेश के एमवीवीएम-लाइट के कार्यान्वयन और INotifyPropertyChanged प्रदान करता है जो आसान है। आप तर्क दे सकते हैं कि यह "शुद्ध" नहीं है लेकिन मुझे नहीं लगता कि यह महत्वपूर्ण है।

2) मैंने एमवीएमएम-लाइट DispatcherHelper.CheckBeginInvokeOnUI सहायक का उपयोग किया जैसा आपने किया था (मेरे मॉडल से, मेरे व्यू मॉडेल नहीं)।

उम्मीद है कि इससे मदद मिलती है।

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