2011-06-30 11 views
5

मुझे एक समय का भालू है कि मेरे व्यू मॉडेल के बाहर एक कक्षा से थ्रेड को कैसे संभालना है।एमवीवीएम व्यू मॉडल में सी # डब्ल्यूपीएफ थ्रेड को कैसे संभालें

थ्रेड Track कक्षा से उत्पन्न होता है।

public delegate void ResponseEventHandler(AbstractResponse response); 
public event ResponseEventHandler OnResponseEvent; 

जब एक "कमांड" विधि मेरी Track वस्तु के भीतर से संसाधित किया जाता है, तो निम्न कोड OnResponseEvent चलाता है, जो वापस मेरी ViewModel करने के लिए एक थ्रेड में एक संदेश भेजता है:: यहाँ Track में ResponseEventHandler कोड है

if (OnResponseEvent != null) 
{ 
    OnResponseEvent(GetResponseFromCurrentBuffer()); 
} 

GetResponseFromCurrentBuffer() केवल एक संदेश प्रकार देता है जो Track के भीतर एक पूर्व परिभाषित प्रकार है।

मेरे MainWindowViewModel निर्माता Track से OnResponseEvent के लिए एक ईवेंट हैंडलर बनाता है:

public MainWindowViewModel() 
{ 
    Track _Track = new Track(); 

    _Track.OnResponseEvent += 
     new Track.ResponseEventHandler(UpdateTrackResponseWindow); 
} 

तो, विचार हर बार जब मैं नया संदेश OnResponseEvent थ्रेड से आ रही है, मैं UpdateTrackResponseWindow() विधि चलने वाले है। इस विधि एक ObservableCollection<string> सूची संपत्ति TrackResponseMessage कहा जाता है के लिए एक नया संदेश स्ट्रिंग संलग्न कर देगा:

private void UpdateTrackResponseWindow(AbstractResponse message) 
{ 
    TrackResponseMessage.Add(FormatMessageResponseToString(message)); 
} 

FormatMessageResponseToString() विधि केवल Track के भीतर सभी पूर्व निर्धारित संदेश प्रकारों के साथ संदेश तुलना, और कुछ गंधा स्ट्रिंग स्वरूपण करता है।

मुख्य समस्या यह है: यूआई गायब हो जाती है जब TrackResponseMessage.Add() चलाया जाता है।

public ObservableCollection<String> TrackResponseMessage 
{ 
    get { return _trackResponseMessage; } 
    set 
    { 
     _trackResponseMessage = value; 
     RaisePropertyChanged("TrackResponseMessage"); 
    } 
} 

वहाँ के लिए एक की जरूरत है: निष्पादन अभी भी पृष्ठभूमि में चल रहा है, और एक ही रास्ता कार्य समाप्त करने के लिए दृश्य स्टूडियो 2010

TrackResponseMessage बंद करने के लिए है मेरी ViewModel के भीतर एक सार्वजनिक संपत्ति है Track ऑब्जेक्ट से मेरे व्यूमोडेल पर आने वाले मार्शल को मार्शल? किसी भी उदाहरण कोड की सराहना की जाएगी!

उत्तर

9

क्या मुझे ट्रैक व्यू ऑब्जेक्ट से मेरे व्यूमोडेल में आने वाले थ्रेड को मार्शल करने की ज़रूरत है? किसी भी उदाहरण कोड की सराहना की जाएगी!

हां। दुर्भाग्यवश, जबकि INotifyPropertyChanged अन्य धागे से घटनाओं को संभालेगा, INotifyCollectionChanged नहीं (यानी: ObservableCollection<T>)। इस तरह, आपको वीएम में वापस मार्शल की जरूरत है।

यदि वीएम व्यू (व्यू-फर्स्ट एमवीवीएम) से बना रहा है या यूआई थ्रेड पर बनाया जाने वाला है, तो इसका उपयोग करने का एक अच्छा विकल्प है।नेट 4 कार्यों:

TaskScheduler uiScheduler; 
public MainWindowViewModel() 
{ 
    uiScheduler = TaskScheduler.FromCurrentSynchronizationContext(); 
    Track _Track = new Track(); 
    _Track.OnResponseEvent += new Track.ResponseEventHandler(UpdateTrackResponseWindow); 
} 

फिर, बाद में, अपने ईवेंट हैंडलर कर सकते हैं:

private void UpdateTrackResponseWindow(AbstractResponse message) 
{ 
    Task.Factory.StartNew(
     () => TrackResponseMessage.Add(FormatMessageResponseToString(message)), 
     CancellationToken.None, TaskCreationOptions.None, 
     uiScheduler); 
} 

यह आपके ViewModel वर्ग में WPF या Silverlight विशिष्ट संसाधनों और प्रकार खींच नहीं की अच्छा लाभ दिया है (यानी:), जबकि अभी भी सभी लाभ प्रदान करते हैं। यह थ्रेड एफ़िनिटी (यानी: डब्ल्यूसीएफ सेवा कार्य) के साथ अन्य दिनचर्या में भी अपरिवर्तित काम करता है।

+0

Yeeehaw !! यह बहुत अच्छा काम किया! रीड, मैं आपको एक डोनट देना चाहता हूं! आपने मुझे .net थ्रेडिंग दस्तावेज़ पढ़ने के घंटे बचाए। टास्कशेड्यूलर मेरे व्यूमोडेल में अन्य क्लास ऑब्जेक्ट्स से इनकमिंग थ्रेड को पढ़ने में आसान बनाता है। – EnLaCucha

+0

@EnLaCucha: FYI - यह केवल उन थ्रेड के लिए काम करता है जिनमें सिंक्रनाइज़ेशन कॉन्टेक्स्ट स्थापित है। डब्ल्यूपीएफ के मुख्य धागे, विनफॉर्म के मुख्य धागे और डब्ल्यूसीएफ सेवा कॉल के लिए यह सच है। –

+0

.NET 4.5 के साथ अब आप BindingOperations का उपयोग करके किसी अन्य थ्रेड से संग्रह संपादित कर सकते हैं। सक्षम कोलेक्शन सिंक्रनाइज़ेशन https://msdn.microsoft.com/en-us/library/hh140164(v=vs.110).aspx – Kelly

0

यदि RaisePropertychanged UI थ्रेड के अलावा किसी थ्रेड पर निष्पादित किया गया है और ईवेंट के लिए ईवेंट हैंडलर UI को छूता है तो आपको UI थ्रेड पर स्विच करने की आवश्यकता होती है।

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