विंडोज फॉर्म थ्रेडिंग और इवेंट्स - लिस्टबॉक्स तुरंत अपडेट करता है लेकिन प्रोग्रेसबार में बड़ी देरी होती है

हमारी टीम एक पुराने भर्ती के लिए एक नई भर्ती वर्कफ़्लो प्रणाली बना रही है। मुझे पुराने डेटा को नए स्कीमा में माइग्रेट करने का काम सौंपा गया है। मैंने एक छोटा विंडोज फॉर्म प्रोजेक्ट बनाकर ऐसा करने का फैसला किया है क्योंकि स्कीमा मूल रूप से अलग है और सीधे टीएसक्यूएल स्क्रिप्ट पर्याप्त समाधान नहीं हैं।

मुख्य मुहरबंद वर्ग 'आयात नियंत्रक' जो काम करता है, निम्नलिखित प्रतिनिधि कार्यक्रम घोषित करता है:

public delegate void ImportProgressEventHandler(object sender, ImportProgressEventArgs e);
public static event ImportProgressEventHandler importProgressEvent;

मुख्य विंडो एक नए धागे का उपयोग कर उस वर्ग में एक स्थिर विधि शुरू करता है:

Thread dataProcessingThread = new Thread(new ParameterizedThreadStart(ImportController.ImportData));
dataProcessingThread.Name = "Data Importer: Data Processing Thread";
dataProcessingThread.Start(settings);

ImportProgressEvent args में एक स्ट्रिंग संदेश होता है, प्रगति पट्टी के लिए अधिकतम int मान और वर्तमान प्रगति int मान होता है। विंडोज फॉर्म घटना के लिए सदस्यता देता है:

ImportController.importProgressEvent += new ImportController.ImportProgressEventHandler(ImportController_importProgressEvent);

और अपने स्वयं के प्रतिनिधि का उपयोग करके इस तरीके से इस घटना का जवाब देता है:

    private delegate void TaskCompletedUIDelegate(string completedTask, int currentProgress, int progressMax);

private void ImportController_importProgressEvent(object sender, ImportProgressEventArgs e)
            {
                this.Invoke(new TaskCompletedUIDelegate(this.DisplayCompletedTask), e.CompletedTask, e.CurrentProgress, e.ProgressMax);
            }

अंत में प्रगति पट्टी और सूची बॉक्स अद्यतन हैं:

private void DisplayCompletedTask(string completedTask, int currentProgress, int progressMax)
        {
            string[] items = completedTask.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);

            foreach (string item in items)
            {
                this.lstTasks.Items.Add(item);
            }

            if (currentProgress >= 0 && progressMax > 0 && currentProgress <= progressMax)
            {
                this.ImportProgressBar.Maximum = progressMax;
                this.ImportProgressBar.Value = currentProgress;
            }
        }

बात यह है कि ListBox बहुत जल्दी अपडेट हो रहा है, लेकिन प्रगति पट्टी कभी नहीं चलता है जब तक कि बैच लगभग पूरी तरह से पूरा नहीं हो जाता ??? क्या देता है ?

0
ro fr bn

6 उत्तर

क्या आप सुनिश्चित हैं कि यूआई थ्रेड इस प्रक्रिया के दौरान स्वतंत्र रूप से चल रहा है? यानी यह एक जॉइन या कुछ अन्य प्रतीक्षा पर अवरुद्ध नहीं बैठा है? यह मेरे जैसा दिखता है।

पृष्ठभूमिवर्कर का उपयोग करने का सुझाव एक अच्छा है - निश्चित रूप से रीफ्रेश/अपडेट कॉल के लोड के साथ समस्या से बाहर निकलने की कोशिश करने के लिए निश्चित रूप से बेहतर है।

और BackgroundWorker पूल थ्रेड का उपयोग करेगा, जो आपके स्वयं के अल्पकालिक धागे बनाने से व्यवहार करने का एक मित्रवत तरीका है।

0
जोड़ा

थ्रेडपूलिंग से कोई लाभ नहीं है   मुझे पता है कि यह केवल एक ही पैदा होगा   धागा। धागे का उपयोग पूरी तरह से है   एसक्यूएल के दौरान एक उत्तरदायी यूआई है   सर्वर को पढ़ने के साथ बढ़ाया जा रहा है और   लिखते हैं। यह निश्चित रूप से एक छोटा नहीं है   थ्रेड रहता था।

ठीक है, मैं इसकी सराहना करता हूं, और आपको खुशी है कि आपको अपनी बग मिली है, लेकिन क्या आपने पृष्ठभूमिवर्कर को देखा है? यह वही करता है जो आप कर रहे हैं, लेकिन एक मानक फैशन (यानी अपने स्वयं के प्रतिनिधियों के बिना) और बिना किसी नए धागे को बनाने की आवश्यकता के - जो दोनों (शायद छोटे, लेकिन शायद अभी भी उपयोगी) फायदे हैं।

0
जोड़ा

हो सकता है कि गुंजाइश के बाहर, कभी-कभी application.DoEvents (); करने के लिए उपयोगी होता है ताकि गुई पार्ट्स उपयोगकर्ता इनपुट पर प्रतिक्रिया दे सकें, जैसे स्टेटस बार संवाद पर रद्द करें बटन दबाएं।

0
जोड़ा

@ जॉन

लिंक के लिए धन्यवाद।

@मर्जी

थ्रेडपूलिंग से कोई लाभ नहीं है क्योंकि मुझे पता है कि यह केवल एक धागा पैदा करेगा। थ्रेड का उपयोग पूरी तरह से एक उत्तरदायी यूआई है जबकि एसक्यूएल सर्वर को पढ़ और लिखने के साथ बढ़ाया जा रहा है। यह निश्चित रूप से एक छोटा सा थ्रेड नहीं है।

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

@सब

आपके सभी इनपुट के लिए धन्यवाद, यह मुझे सोच रहा है, जो मुझे कोड में कहीं और देख रहा था, जिसने नम्रता के मेरे आह क्षण को जन्म दिया जहां मैं साबित करता हूं कि त्रुटि अभी भी मानव है :)

0
जोड़ा

क्या आप किसी भी मौके से विंडोज विस्टा चलाते हैं? मैंने कुछ काम से संबंधित अनुप्रयोगों में बिल्कुल वही बात देखी है। किसी भी तरह, प्रगति पट्टी "एनिमेटेड" होने पर देरी हो रही है।

0
जोड़ा

शायद आप BackgroundWorker घटक आज़मा सकते हैं। यह थ्रेडिंग आसान बनाता है। यहां उदाहरण:

0
जोड़ा