2013-03-14 5 views
5

मेरे wpf (C#) एप्लिकेशन में, उपयोगकर्ता द्वारा बटन दबाए जाने पर एक लंबी प्रक्रिया की जाती है। जब बटन को दबाया जाता है तब तक बटन दबाया जाता है जब तक कि विंडो को फ्रीज निष्पादित नहीं किया जाता है और उपयोगकर्ता विंडो में कोई अन्य कार्य नहीं कर सकता है। मैं पृष्ठभूमि प्रक्रिया के रूप में बटन क्लिक कोड कैसे बना सकता हूं, ताकि विंडो उपयोगकर्ता के लिए उत्तरदायी हो। मैंने निम्न विधि का प्रयास किया है, लेकिन असफल रहा।बटन क्लिक होने पर wpf UI उत्तरदायी बनाएं

private void btn_convert_Click(object sender, RoutedEventArgs e) 
{ 
    Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, 
    new Action(() => { 

     WorkerMethod(); 
    })); 
} 

जहां वर्कर मोड संपूर्ण कोड के साथ कार्य है। कोई सुझाव

सादर,
संगीता

उत्तर

5

क्या आप वास्तव में यहाँ किया है अपने भारी काम चलाने के लिए यूआई धागा पूछ रहा है ।

डिस्पैचर के माध्यम से आप एक नया धागा/कार्य बना सकते हैं और यह अपनी पृष्ठभूमि विधि चलाते हैं चाहिए:

Thread t = new Thread(() => WorkerMethod()); 
t.Start(); 
अधिक जानकारी के लिए इस पढ़ने के लिए

:

WPF BackgroundWorker vs. Dispatcher

Understanding “Dispatcher” in WPF

+1

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

+0

@Sangeetha उन्हें सक्षम/अक्षम करने के लिए डिस्पैचर का उपयोग करें – makc

1

आप UI-Dispatcher पर विधि बुला रहे हैं, इस यूआई फ्रीज कर देगा। आपके क्लिक-घटना में एक नया सूत्र "System.Threading.Thread` के बारे में जानकारी के लिए

private void btn_convert_Click(object sender, RoutedEventArgs e) 
    { 
     Thread t = new Thread(new ThreadStart(WorkerMethod)); 
     //assign STA or MTA, etc.... 
     t.Start(); 
    } 

देखो here का उपयोग कर बनाएँ।

+0

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

+1

@ संगीता आपको यूआई-डिस्पैचर की कतार में अपना अनुरोध कतार देना होगा। देखो [यहां] (http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcherobject.checkaccess.aspx) और दिखाए गए अनुसार आगे बढ़ें। –

7

जवाब के लिए एक वैकल्पिक यहाँ एक BackgroundWorker है। यह आपके द्वारा किए जाने के बाद जीयूआई थ्रेड पर लौटने का अतिरिक्त लाभ है।

private void btn_convert_Click(object sender, RoutedEventArgs e) 
{ 
    BackgroundWorker worker = new BackgroundWorker(); 
    worker.DoWork += WorkerMethod; 
    worker.RunWorkerCompleted += WorkerEnded; 
    worker.RunWorkerAsync(); 
} 

private void WorkerMethod() 
{ 
    // New thread, cannot access GUI 
} 

private void WorkerEnded() 
{ 
    // Back on the GUI Thread 
    // Worker is finished 
} 
+0

मैं थ्रेडिंग के लिए नया हूं, – Karthik

0

पृष्ठभूमि कार्यकर्ता वर्ग का उपयोग करने का प्रयास करें। आपको DoWork ईवेंट में पंजीकरण करना होगा और एक ईवेंट हैंडलर बनाना होगा जहां आपने अपना सभी प्रोसेसिंग कोड डाला होगा। आप वर्कर्स को RunWorkerAsync विधि से प्रारंभ करते हैं। एक ऐसी विधि भी है जो आपके श्रमिकों की रिपोर्ट "रिपोर्ट प्रोग्रेस" की प्रगति कर सकती है। RunWorker पूर्ण आपको दिखाएगा जब आपका कार्यकर्ता आपके कोड को संसाधित कर लेता है। BackgroundWorker के बाद इंटरनेट पर खोज करने के लिए प्रयास करें और आप कैसे यह

10

उपयोग करने के लिए आपको .NET 4.5 लक्षित कर रहे हैं, तो आप अपने यूआई उत्तरदायी बनाने के लिए उपयोग कर सकते हैं async/await उदाहरण मिल जाएंगे:

private async void btn_convert_Click(object sender, RoutedEventArgs e) 
{ 
    await WorkerMethod(); 
} 

संशोधित अपने WorkerMethod:

private Task WorkerMethod() 
{ 
    return Task.Run(() => 
     { 
      // your long running task here 
     }); 
} 
+2

समझने के लिए यह सरल और स्पष्ट पाएं। क्या आप इस कोड को समझा सकते हैं? एसिंक और कीवर्ड का इंतजार क्या करते हैं? – Doug

1

मैं एक तरह से मैं काफी गर्व कर रहा हूँ कल्पना: multithread मामले में , केवल IHM एक प्रगति बार चेतन करने के लिए अनुमति देने के लिए लाभ है, तो उपयोगकर्ता टी के साथ बातचीत करने वाले नहीं है वह IH ​​प्रक्रिया को ठीक कर रहा है या बस यदि मल्टीथ्रेडिंग को विकसित करने का कोई समय नहीं है और आप बिना किसी प्रतिक्रिया के अपने आवेदन को फ्रीज करने की अनुमति दे सकते हैं:

आप एक अन्य एसटीए थ्रेड में लॉन्च लोडर विकसित कर सकते हैं जिसने एक और विंडो बनाई और इस लोडर को प्रदर्शित किया जमे हुए खिड़की के बीच।

private void MainWindow_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
{ 
    // Long UI process context 
    using (new LongUIProcessContext("Wait while loading...")) 
    { 
     Thread.Sleep(2000); 

     // Sub long ui process context 
     using (new LongUIProcessContext("Wait while loading 2...")) 
     { 
      Thread.Sleep(2000); 
     } 

     // Another sub long ui process context 
     using (new LongUIProcessContext("Wait while loading 3...")) 
     { 
      Thread.Sleep(2000); 
     } 
    } 
} 

और यहाँ है:

http://charly-studio.com/blog/a-loader-for-wpf-long-ui-process/

यहाँ कैसे मैं अपने घटक का उपयोग है:

यहाँ एक पोस्ट है जहाँ से मैंने एक लेख और इस तरह के एक समाधान के एक कार्यान्वयन बना दिया है मैं जो बेंच प्रस्तावित करता हूं वह इस तरह दिखता है: long Ui process bench

और यहां बेंच का सीधा लिंक है

The bench solution direct download

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