मेरी MVVM आवेदन मेरे विचार मॉडल 3 अलग सेवा तरीकों कहता है, में एक आम प्रारूप में प्रत्येक से डेटा धर्मान्तरित और फिर सेवा परत में प्रत्येक विधि एक नया शुरू होता है संपत्ति अधिसूचना/नमूदार संग्रह आदिUI थ्रेड को अवरोधित किए बिना एकाधिक कार्य के बाद मैं कैसे जारी रखूं?
का उपयोग कर यूआई अद्यतन करता है Task
और दृश्य मॉडल में Task
देता है। यहां मेरी सेवा विधियों में से एक का उदाहरण दिया गया है।
public class ResourceService
{
internal static Task LoadResources(Action<IEnumerable<Resource>> completedCallback, Action<Exception> errorCallback)
{
var t = Task.Factory.StartNew(() =>
{
//... get resources from somewhere
return resources;
});
t.ContinueWith(task =>
{
if (task.IsFaulted)
{
errorCallback(task.Exception);
return;
}
completedCallback(task.Result);
}, TaskScheduler.FromCurrentSynchronizationContext());
return t;
}
}
यहाँ बुला कोड और देखने मॉडल के अन्य प्रासंगिक भागों है ...
private ObservableCollection<DataItem> Data = new ObservableCollection<DataItem>();
public ICollectionView DataView
{
get { return _dataView; }
set
{
if (_dataView != value)
{
_dataView = value;
RaisePropertyChange(() => DataView);
}
}
}
private void LoadData()
{
SetBusy("Loading...");
Data.Clear();
Task[] tasks = new Task[3]
{
LoadTools(),
LoadResources(),
LoadPersonel()
};
Task.WaitAll(tasks);
DataView = CollectionViewSource.GetDefaultView(Data);
DataView.Filter = FilterTimelineData;
IsBusy = false;
}
private Task LoadResources()
{
return ResourceService.LoadResources(resources =>
{
foreach(var r in resources)
{
var d = convertResource(r);
Data.Add(d);
}
},
error =>
{
// do some error handling
});
}
यह लगभग काम करता है लेकिन छोटे मुद्दों के एक जोड़े हैं।
संख्या 1: बहुत शुरुआत में SetBusy
पर कॉल करने से पहले, मैंने कोई कार्य शुरू करने से पहले और WaitAll
पर कॉल करने से पहले, मैंने IsBusy
संपत्ति को सत्य पर सेट किया था। यह यूआई को अपडेट करना चाहिए और BusyIndicator नियंत्रण दिखाएं लेकिन यह काम नहीं कर रहा है। मैंने सरल स्ट्रिंग गुण जोड़ने और उनको बाध्य करने का भी प्रयास किया है और उन्हें या तो अपडेट नहीं किया जा रहा है। IsBusy कार्यक्षमता बेस क्लास का हिस्सा है और अन्य दृश्य मॉडल में काम करती है जहां मेरे पास एक से अधिक कार्य चलाना नहीं है, इसलिए मुझे विश्वास नहीं है कि XAML में संपत्ति अधिसूचना या डेटा बाध्यकारी के साथ कोई समस्या है।
पूरी विधि पूरी होने के बाद सभी डेटा बाइंडिंग अपडेट होने लगते हैं। मुझे आउटपुट विंडो में कोई भी "पहली बार अपवाद" या बाध्यकारी त्रुटियां नहीं दिखाई दे रही हैं, जो मुझे विश्वास दिलाती हैं कि यूआई थ्रेड को किसी भी तरह से प्रतीक्षा करने के लिए अवरुद्ध किया जा रहा है।
संख्या 2: मैं सेवा विधियों से गलत कार्य वापस कर रहा हूं। दृश्य मॉडल के बाद कॉलबैक में सभी सेवा विधियों से सभी परिणामों को परिवर्तित करने के बाद मुझे WaitAll
के बाद सबकुछ चाहिए। हालांकि अगर मैं सेवा विधि से निरंतरता कार्य वापस करता हूं तो निरंतरता कभी नहीं बुलाती है और WaitAll
हमेशा के लिए प्रतीक्षा करता है। अजीब बात यह है कि आईसीओलेक्शन व्यू के लिए यूआई नियंत्रण वास्तव में सब कुछ सही तरीके से प्रदर्शित करता है, मुझे लगता है कि ऐसा इसलिए है क्योंकि डेटा एक अवलोकन संग्रह है और संग्रहव्यूसोर्स संग्रहित घटनाओं के बारे में पता है।
मैं एसिंक/प्रतीक्षा का उपयोग कर बंद कर रहा हूं क्योंकि मुझे यकीन नहीं है कि यह WPF कमांड और प्रिज्म प्रतिनिधिमंडल के साथ "बस काम करता है"। कार्य। CONTinueWhenAll मेरे लिए मौजूद प्रतीत नहीं होता है, क्या मुझे कुछ टीपीएल एक्सटेंशन लाइब्रेरी का संदर्भ देने की आवश्यकता है? – BenCr
@BenCr क्षमा करें- यह कार्य FactoryFontinContinueWhenAll। आम तौर पर, प्रतीक्षा/async सामान WPF के साथ कार्य निरंतरता की तुलना में * बेहतर * काम करता है। मुख्य अंतर यह है कि अपवादों को संभालने के लिए आपको पागल हुप्स से कूदना नहीं है। –
धन्यवाद रीड, ऐसा लगता है कि यह बहुत बेहतर काम कर रहा है। उम्मीद है कि कोई भी WaitAll को कॉल करने से पहले अवरुद्ध करने के लिए स्पष्टीकरण प्रदान करने में सक्षम हो सकता है लेकिन इसने निश्चित रूप से 1 और 2 के मुद्दों को ठीक कर दिया है। मैं अगले पुनरावृत्ति में एसिंक/प्रतीक्षा सामग्री दूंगा और देखें कि मैं कैसे चल रहा हूं। – BenCr