यूआई थ्रेड पर इन नियंत्रणों को बनाने से कोई परहेज नहीं है, लेकिन आप एसिंक्रोनस ऑपरेशंस की अनुमति देने के लिए टास्क समांतर लाइब्रेरी (टीपीएल) से System.Threading.Tasks.Task
का लाभ उठा सकते हैं।
मैं इस तरह की संरचना के साथ चांदी की रोशनी 5 में ऐसा कुछ करने में सक्षम हूं। Caliburn.Micro के स्रोत को देखने के मूल विचार मिला।
निम्नलिखित एक सबसेट है जो आप चाहते हैं कि लागू होता है।
public interface IPlatformProvider {
/// <summary>
/// Executes the action on the UI thread asynchronously.
/// </summary>
/// <param name = "action">The action to execute.</param>
System.Threading.Tasks.Task OnUIThreadAsync(Action action);
}
यहां कार्यान्वयन है।
/// <summary>
/// A <see cref="IPlatformProvider"/> implementation for the XAML platfrom (Silverlight).
/// </summary>
public class XamlPlatformProvider : IPlatformProvider {
private Dispatcher dispatcher;
public XamlPlatformProvider() {
dispatcher = System.Windows.Deployment.Current.Dispatcher;
}
private void validateDispatcher() {
if (dispatcher == null)
throw new InvalidOperationException("Not initialized with dispatcher.");
}
/// <summary>
/// Executes the action on the UI thread asynchronously.
/// </summary>
/// <param name = "action">The action to execute.</param>
public Task OnUIThreadAsync(System.Action action) {
validateDispatcher();
var taskSource = new TaskCompletionSource<object>();
System.Action method =() => {
try {
action();
taskSource.SetResult(null);
} catch (Exception ex) {
taskSource.SetException(ex);
}
};
dispatcher.BeginInvoke(method);
return taskSource.Task;
}
}
आप या तो नीचे निर्माता डि मार्ग जाना प्रदाता में पास या इस तरह एक स्थिर लोकेटर पैटर्न का उपयोग करने के लिए कर सकता है।
/// <summary>
/// Access the current <see cref="IPlatformProvider"/>.
/// </summary>
public static class PlatformProvider {
private static IPlatformProvider current = new XamlPlatformProvider();
/// <summary>
/// Gets or sets the current <see cref="IPlatformProvider"/>.
/// </summary>
public static IPlatformProvider Current {
get { return current; }
set { current = value; }
}
}
अब आप अगर डिस्पैचर करने के लिए कई कॉल करने के लिए किसी भी प्रदर्शन के मुद्दों की वजह से आप के बजाय पूरी प्रक्रिया को स्थानांतरित कर सकता है मुख्य थ्रेड अवरुद्ध और ठंड यूआई
public class BasicContainer : UserControl {
public async Task CreateMultipleActivityControls() {
var platform = PlatformProvider.Current;
for (var i = 0; i < 1000; i++) {
await platform.OnUIThreadAsync(() => {
var c = new ActivityControl();
c.LoadSubControls();
});
}
}
}
के बिना अपने कॉल करने के लिए सक्षम होना चाहिए एक एसीएनसी कॉल करने के लिए।
public class BasicContainer : UserControl {
public async Task CreateMultipleActivityControls() {
var platform = PlatformProvider.Current;
await platform.OnUIThreadAsync(() => {
for (var i = 0; i < 1000; i++) {
var c = new ActivityControl();
c.LoadSubControls();
}
});
}
}
क्या सभी नियंत्रण सीधे गुई में देखे जाते हैं? आप उन्हें आलसी बना सकते हैं? –
"LoadSubControls" विधि में मैं एक छवि उत्पन्न करने के लिए सबस्ट्रक्शंस के अद्यतन Layout को व्यवस्थित करता हूं। क्या आपका मतलब है कि मुझे InitializeComponent() नहीं चलाना चाहिए? – George
मैं आपकी विधि को छोटे टुकड़ों में विभाजित करने के लिए भी जाऊंगा और हर बार आपको ui थ्रेड पर वापस कॉल करूंगा जब आपको वास्तव में यूई में नियंत्रण रखना होगा। –