WinRT

2012-05-14 15 views
63

में यूआई थ्रेड पर कोड चलाएं मैं WinRT (विंडोज 8 मेट्रो) में यूआई थ्रेड पर कोड कैसे चला सकता हूं?WinRT

Invoke विधि मौजूद नहीं है।

+7

नोट:: - एक से अधिक यूआई धागे और प्रेषकों हैं याद रखें, कि यदि आपका ऐप एकाधिक खिड़कियां है मैं इसे हल करने के लिए इस का उपयोग कर समाप्त हो गया। –

उत्तर

68

उपयोग:

अपने यूआई धागा से, निष्पादित करें:

var dispatcher = Windows.UI.Core.CoreWindow.GetForCurrentThread().Dispatcher; 

अपनी पृष्ठभूमि (गैर यूआई धागा) से

dispatcher.RunAsync(DispatcherPriority.Normal, 
    <lambda for your code which should run on the UI thread>); 

कि दोनों सी.पी. पर काम करते हैं और बाद में करना चाहिए बनाता है।

+5

क्या गैर-यूआई थ्रेड पर प्रेषक प्राप्त करने का कोई तरीका है? वर्तमान में मुझे CoreWindow.GetForCurrentThread() – Grigory

+3

सं। प्रेषक एक UI थ्रेड से बंधे हैं, इसलिए आपको UI थ्रेड पर प्रेषक को पुनर्प्राप्त करने की आवश्यकता है।एक बार प्रेषक को पुनर्प्राप्त कर लिया गया है, तो आप इसे याद कर सकते हैं। यदि आप XAML एप्लिकेशन में हैं, तो अधिकांश UI ऑब्जेक्ट्स में प्रेषक सदस्य होता है जिसका आप उपयोग कर सकते हैं। –

+0

तो मेरे ऐप के कौन से हिस्से वास्तव में यूआई थ्रेड में चल रहे हैं? मैं फ़्रेमवर्क्स व्यू (विंडोज़ :: एप्लिकेशन मॉडल :: कोर :: IFrameworkView) का उपयोग कर रहा हूं, और रन() - विधि से प्राप्त प्रेषक का उपयोग करने में सक्षम नहीं हूं। जब मैं RunAsync के माध्यम से MediaElement बनाने की कोशिश कर रहा हूं तो मुझे WrongThreadException मिल रहा है। – Habba

8

उपयोग:

this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,() => Frame.Navigate(typeof(Welcome), this)); 

यह मेरे लिए काम करता है।

+3

यह करता है वास्तव में यूआई थ्रेड पर इसे चलाने की गारंटी नहीं है। यह केवल तभी होगा जब "यह" यूआई संदर्भ में एक वस्तु है। – Luke

5

यह मेरी राय में एक आसान तरीका है।

यूआई से जुड़े टास्कशेड्यूलर प्राप्त करें।

var UISyncContext = TaskScheduler.FromCurrentSynchronizationContext(); 

फिर एक नया कार्य शुरू करें और उपर्युक्त UISyncContext पर।

Task.Factory.StartNew(() => { /* Do your UI stuff here; */}, new System.Threading.CancellationToken(), TaskCreationOptions.PreferFairness, UISyncContext); 
+0

FYI: मुझे एक अवैधऑपरेशन अपवाद मिलता है "वर्तमान सिंक्रनाइज़ेशन कॉन्टेक्स्ट को टास्कशेड्यूलर के रूप में उपयोग नहीं किया जा सकता है"। – Akku

+0

मुझे एक अवैधऑपरेशन – LowDev1

+1

भी मिलता है आपका सिंक्रनाइज़ेशन कॉन्टेक्स्ट शून्य है। यही कारण है कि आप उस अपवाद को प्राप्त कर रहे हैं। मेरे कोड के साथ कुछ भी गलत नहीं है। – Deeb

75

यह सीधे CoreWindow गैर यूआई धागे से प्राप्त करने के लिए आसान है। निम्नलिखित कोड हर जगह काम करेगा, भले ही GetForCurrentThread() या Window.Currentशून्य लौटाता है।

CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, 
    <lambda for your code which should run on the UI thread>); 
उदाहरण के लिए

:

CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, 
    () => 
    { 
     // Your UI update code goes here! 
    }); 

आप संदर्भ के लिए Windows.ApplicationModel.Core नाम स्थान की आवश्यकता होगी:

using Windows.ApplicationModel.Core; 
+0

मुझे इसका उपयोग करते समय System.NotImplementedException मिलता है। मैं इसे यूआई थ्रेड से एक्सेस करता हूं। – Naren

+0

यहां कभी भी यह अपवाद नहीं था। यह कहीं और से हो सकता है, जैसे कि आपके ब्लॉक निर्देशों के अंदर। –

+0

जब मैं डिस्पैचर तक पहुंचने का प्रयास करता हूं तो मुझे यह अपवाद मिलता है। मैंने प्रेषक का उपयोग करके किसी भी कोड को निष्पादित नहीं किया है। – Naren

0

DispatcherTimer भी एक विकल्प है।

मैं कोड है कि Xaml-डिजाइनर में चला जाना चाहिए के लिए यह प्रयोग किया जाता (CoreWindow.Dispatcher, ... नहीं उपलब्ध UWP-डिजाइनर में हैं)

var localTimer = new DispatcherTimer 
{ 
    Interval = TimeSpan.FromMilliseconds(0) 
}; 
localTimer.Tick += (timer, e) => 
{ 
    (timer as DispatcherTimer).Stop(); 
    action(); 
}; 
localTimer.Start(); 

अस्वीकरण:
मैं नोट करना चाहिए कि इस करना चाहिए यदि हर दूसरे विफल रहता है तो एक अंतिम उपाय विकल्प बनें।

0

यूडब्ल्यूपी पर, मुझे कैप्चर एलिमेंट कंट्रोल (जिसे एक्सएएमएल में परिभाषित किया गया है) की स्रोत प्रॉपर्टी सेट करने की कोशिश करने में समस्या हो रही थी, यह अलग-अलग धागे पर तैयार होने के बारे में शिकायत कर रहा था, भले ही मैं इसे कोड से सेट करने की कोशिश कर रहा था पेज_लोडेड ईवेंट हैंडलर के माध्यम से आमंत्रित किया गया। भविष्य पाठकों के लिए

previewControl.Dispatcher.TryRunAsync(CoreDispatcherPriority.Normal,() => { 
    previewControl.Source = _mediaCapture; 
}).GetAwaiter().GetResult(); 

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