2012-01-22 14 views
8

मेरे पास एक विकल्प विंडो और एक विंडो है जो इन विकल्पों और किनेक्ट डेटा के आधार पर रंग प्रदर्शित करती है। अब तक सब कुछ एक धागे पर है (जहां तक ​​मुझे पता है; मैंने कोई थ्रेडिंग नहीं किया है)।मैं एक नए धागे पर एक विंडो कैसे खोलूं?

अब, मैं एक दर्शक विंडो खोलने के लिए एक विकल्प जोड़ रहा हूं जिसे सबसे कम संभव विलंबता के साथ अद्यतन करने की आवश्यकता होगी। सभी इस जरूरत पर जोर देता एक खिड़की को बनाने और उसे दिखा रहा है:

viewer = new SkeletalViewer.MainWindow(); 
viewer.Show(); 

जब इस घटना की आग, रंग खिड़की रंगों को प्रदर्शित करने बंद हो जाता है (यानी घटना मुख्य थ्रेड पर 30 बार एक दूसरे आग कि फायरिंग बंद हो जाता है), लेकिन दर्शक पूरी तरह से प्रदर्शित किया जाता है। मैं चाहता हूं कि दर्शक और रंगीन विंडो दोनों को अपडेट किया जाए।

अन्य प्रश्न पढ़ने से, ऐसा लगता है कि दर्शक को नए थ्रेड पर दर्शक बनाना है। हालांकि, मुझे इसके साथ कई समस्याएं आ रही हैं।

यह आग जब मैं दर्शक खोलने के लिए बटन पर क्लिक करें:

private void launchViewerThread_Click(object sender, RoutedEventArgs e) 
    { 
     Thread viewerThread = new Thread(delegate() 
     { 
      viewer = new SkeletalViewer.MainWindow(); 
      viewer.Dispatcher.Invoke(new Action(delegate() 
       { 
        viewer.Show(); 
       })); 
     }); 

     viewerThread.SetApartmentState(ApartmentState.STA); // needs to be STA or throws exception 
     viewerThread.Start(); 

    } 

अगर मैं viewer.Show() या आह्वान (फोन की परवाह किए बिना) यह रूप में ऊपर, लाइन एक अपवाद फेंकता है: नहीं कर सकते एक निर्भरता ऑब्जेक्ट का उपयोग करें जो उसके माता-पिता फ्रीज़ेबल की तुलना में एक अलग धागे से संबंधित है। यहां बताया गया है कि मैं Invoke() को कैसे समझता हूं: यह दर्शक के प्रेषक तक पहुंचता है, जो जानता है कि वस्तु किस धागे पर चल रही है, और उसके बाद उस थ्रेड से विधियों को कॉल कर सकते हैं।

क्या मुझे इस दर्शक को नए धागे पर रखने की कोशिश करनी चाहिए? क्या समस्या भी धागे का सवाल है? उपयोगकर्ता दर्शक के साथ बातचीत नहीं करेगा।

कोई भी जानता है कि यह क्यों काम नहीं करता है? सहायता के लिए धन्यवाद।

उत्तर

15

आप एक ही धागे पर Show() कॉल करने की आवश्यकता है, तो चलो इस के साथ कुछ code-

in the constructor register this 
    public MainWindow() 
    { 
     UpdateColorDelegate += UpdateColorMethod; 
    } 

    // delegate and event to update color on mainwindow 
    public delegate void UpdateColorDelegate(string colorname); 
    public event UpdateColorDelegate updateMainWindow; 

    // launches a thread to show viewer 
    private void launchViewerThread_Click(object sender, RoutedEventArgs e) 
    { 
     Thread t = new Thread(this.ThreadProc); 
     t.Start(); 
    } 

    // thread proc 
    public void ThreadProc() 
    { 
     // code for viewer window 
     ... 
     // if you want to access any main window elements then just call DispatchToMainThread method 
     DispatchToUiThread(color); 
    } 

    // 
    private void DispatchToUiThread(string color) 
    { 
     if (updateMainWindow != null) 
     { 
     object[] param = new object[1] { color}; 
     Dispatcher.BeginInvoke(updateMainWindow, param); 
     } 
    } 

    // update the mainwindow control's from this method 
    private void UpdateColorMethod(string colorName) 
    { 
     // change control or do whatever with main window controls 
    } 

है कि खिड़की पर बनाया गया है - यही कारण है कि आपको त्रुटि मिल रही है। फिर आपको विंडो का प्रबंधन करने के लिए रनटाइम प्राप्त करने के लिए एक नया डिस्पैचर उदाहरण भी शुरू करने की आवश्यकता है। http://msdn.microsoft.com/en-us/library/ms741870.aspx

+0

मुझे यह कहते हुए आमंत्रण दिखाई देता है कि दर्शक() को शो() पर कॉल किया जा रहा है । यहां तक ​​कि दर्शक के आस-पास आमंत्रण() के बिना भी। दिखाएं(), मुझे अभी भी फ्रीज करने योग्य अपवाद मिलता है। –

+0

@ michael.greenwald फिर 'SkeletalViewer.MainWindow()' में कुछ है जो अपवाद पैदा कर रहा है। मैंने एक खाली WPF प्रोजेक्ट बनाया जो वास्तव में ऊपर दिखाता है और यह अपवाद के बिना चलता है। हो सकता है कि आप इस प्रश्न से समस्या के समान हैं: http://stackoverflow.com/questions/3636761/how-to-debug-this-error-when-none-of-my-code-shows-up-in- द स्टैक – shf301

+0

और उस विंडो को 'लॉन्च व्यूअर थ्रेड' से कैसे बंद करें? –

0

मुझे यकीन नहीं है कि यह आपकी समस्या का समाधान करेगा या नहीं, लेकिन क्या आप एक थ्रेड प्रो (एक दर्शक विंडो खोलने के लिए) बनाने की कोशिश कर सकते हैं जिसे एक अलग थ्रेड पर निष्पादित किया जाता है और उसके बाद एक विवादक है .beginInvoke मुख्य विंडो को अद्यतन करने के लिए,

यहाँ आप यह ठंड के बिना मुख्य विंडो नियंत्रण अद्यतन कर सकते हैं, मुझे पता है आप किसी भी सवाल

+0

धन्यवाद। आप UI थ्रेड पर रंग क्यों भेजते हैं? यूआई थ्रेड, डिफ़ॉल्ट थ्रेड पर कोई भी बुलाया जाने वाला तरीका नहीं बुलाया जा रहा है? –

+0

क्योंकि मुख्य UI थ्रेड से निकाला गया पृष्ठभूमि थ्रेड UI थ्रेड पर बनाए गए किसी भी नियंत्रण की सामग्री को अपडेट नहीं कर सकता है।पृष्ठभूमि धागे को मुख्य विंडो पर नियंत्रण तक पहुंचने के लिए, पृष्ठभूमि थ्रेड को यूआई थ्रेड से जुड़े डिस्पैचर को काम सौंपना होगा। यह या तो Invoke या BeginInvoke का उपयोग करके पूरा किया जाता है। Invoc सिंक्रोनस है और BeginInvoke asynchronous है। निर्दिष्ट डिस्पैचर प्राथमिकता पर डिस्पैचर की घटना कतार में ऑपरेशन जोड़ा जाता है। – DotNetUser

+0

यह लिंक देखें - http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher.begininvoke.aspx – DotNetUser

1

तो मैं एक ऐसी ही समस्या का समाधान एक नई विंडो एक नया धागा पर खोलने में विफल रहा में चल रहा था:

private void launchViewerThread_Click(object sender, RoutedEventArgs e) 
{ 
    Thread viewerThread = new Thread(delegate() 
    { 
     viewer = new SkeletalViewer.MainWindow(); 
     viewer.Show(); 
     System.Windows.Threading.Dispatcher.Run(); 
    }); 

    viewerThread.SetApartmentState(ApartmentState.STA); // needs to be STA or throws exception 
    viewerThread.Start(); 
} 

पर एकाधिक विंडोज़/एकाधिक धागे उदाहरण देखें। अपवाद "एक निर्भर थ्रेड से संबंधित निर्भरता का उपयोग नहीं कर सकता"।

समस्या यह समाप्त हो गई कि खिड़की वैश्विक संसाधन (पृष्ठभूमि ब्रश) का उपयोग कर रही थी। एक बार जब मैं ब्रश संसाधन जमा कर देता हूं, तो खिड़की बस ठीक हो जाती है।

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