2011-06-12 7 views
5

मुझे कुछ गलत करने की कोशिश करने की कोशिश करने में कुछ मदद चाहिए। संग्रह प्रक्रिया के दौरान फ़ॉर्म को जमे हुए रखने के लिए मैं एक अलग थ्रेड पर सिस्टम लॉग से आइटम्स का संग्रह प्राप्त करने का प्रयास कर रहा हूं। मैं पृष्ठभूमि कार्यकर्ता को उन सभी को पकड़ने के लिए प्राप्त कर सकता हूं, लेकिन मुझे कुछ समस्याएं हैं, उन्हें फॉर्म पर ListBox पर जोड़ें।धागे के साथ काम करना सी #

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
{ 

    foreach (System.Diagnostics.EventLogEntry entry in eventLog1.Entries) 
    { 
    listBox1.Items.Add(
     entry.EntryType.ToString() + " - " + 
     entry.TimeWritten + "  - " + 
     entry.Source); 
    } 
} 

जाहिर है इस उम्मीद के रूप में के बाद से वहाँ 2 अलग धागे हैं काम नहीं करता है, और आप अलग अलग धागे पर वस्तुओं को बदल नहीं सकते, के रूप में मुझे पता चला है। तो, अगर कोई मुझे सही दिशा में मार्गदर्शन कर सकता है, तो मैं आभारी रहूंगा।

+1

इस जवाब पर एक नज़र डालें: http://stackoverflow.com/questions/1136399/how-to -update-पाठ बॉक्स-ऑन-जीयूआई-से-एक और धागा-इन-सी # – Klinger

उत्तर

4

आपको यूआई तत्वों को गैर-यूआई थ्रेड से एक्सेस नहीं करना चाहिए। ReportProgress चलाएं, जिसे यूआई थ्रेड के साथ समन्वयित किया जाएगा।

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
{ 
    foreach (System.Diagnostics.EventLogEntry entry in eventLog1.Entries) 
    { 
     var newEntry = entry.EntryType + " - " + entry.TimeWritten + "  - " + entry.Source; 
     backgroundWorker1.ReportProgress(0, newEntry); 
    } 
} 

void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) 
{ 
    var newEntry = (string)e.UserState; 
    listBox1.Items.Add(newEntry); 
} 

सुनिश्चित करें कि आप WorkerReportsProgress सक्षम करें। एक और दृष्टिकोण

backgroundWorker1.WorkerReportsProgress = true; 

और ProgressChanged

backgroundWorker1.ProgressChanged += backgroundWorker1_ProgressChanged; 

करने के लिए सदस्यता के अंदर

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
{ 
    foreach (System.Diagnostics.EventLogEntry entry in eventLog1.Entries) 
    { 
     var newEntry = entry.EntryType.ToString() + " - " + entry.TimeWritten + "  - " + entry.Source; 
     Action action =() => listBox1.Items.Add(newEntry); 
     Invoke(action); 
    } 
} 

Control.Invoke कॉल करने के लिए लेकिन इस दृष्टिकोण के साथ आप पूरे मुद्दे के रूप में BackgroundWorker की जरूरत नहीं है की इसका इस्तेमाल करने की है ProgressChanged और RunWorkerCompleted इवेंट हैंडलर जो यूआई थ्रेड के साथ समन्वयित हैं।

1

आपको पृष्ठभूमि कार्यकर्ता की रिपोर्ट प्रगति विकल्प का उपयोग करने की आवश्यकता है। google this

0

केवल जीयूआई थ्रेड को जीयूआई तत्वों को संशोधित करने की अनुमति है। यदि आप इस नियम का सम्मान नहीं करते हैं, तो आपको अपवाद मिलेगा। आप हो सकता है:

  1. एक MethodInvoker का उपयोग जीयूआई धागा
  2. भीतर से एक फोन को गति प्रदान करने ब्यौरा निकाला सुविधा (जो आप के लिए वास्तव में 1. करता है)
  3. दुकान एक और डेटा संरचना में वस्तुओं का उपयोग करें (ताला) और वस्तुओं को खींचने और उन्हें प्रदर्शित करने के लिए जीयूआई थ्रेड में टाइमर का उपयोग करें।
1

कोई समस्या नहीं होनी चाहिए क्योंकि आप BackgroundWorker का उपयोग कर रहे हैं। कॉलबैक विधि के लिए सभी कॉल एक ही यूआई संदर्भ पर चलता है।

संपादित करें:

अगर आप प्रगति रिपोर्ट करना चाहते हैं, तो आप SynchronizationContext.Current को बेहतर स्टार्टअप स्टोर करने के लिए की जरूरत है। या आप IsInvokeRequired पैटर्न का उपयोग कर सकते हैं। यहाँ मैं SynchronizationContext

private SynchronizationContext uiContext; 
     public Form1() 
     { 
      uiContext = SynchronizationContext.Current; 
      InitializeComponent(); 
      FillItem(); 
     } 

मैं कोड निम्नलिखित है कैसे उपयोग है, और यह आकर्षण की तरह काम कर रहा है।

public void FillItem() 
      { 
       BackgroundWorker worker = new BackgroundWorker(); 
       worker.WorkerReportsProgress = true; 
       worker.DoWork += (a, b) => 
            { 
             int i = 0; //Percentage complete, roll your own logic. 
             foreach (var eventLog in EventLog.GetEventLogs()) 
             { 
              foreach (EventLogEntry entry in eventLog.Entries) 
              { 
               this.listBox1.Items.Add(entry.Message); 
uiContext.Post(z=>worker.ReportProgress(i++),null); 

              } 
             } 


            }; 
       worker.RunWorkerAsync(); 
       worker.ProgressChanged += (a, b) => this.progressBar1.Value = b.ProgressPercentage; 


      } 
1

इस नियंत्रण के धागे पर एक कार्रवाई लागू की बहुत ही सरल तरीका कोशिश करें,:

private void Form1_Load(object sender, EventArgs e) 
{ 
    var bw = new BackgroundWorker(); 
    bw.DoWork += DoWork; 
    bw.RunWorkerAsync(); 
} 
private void DoWork(object sender, DoWorkEventArgs e) 
{ 
    var itemList = new List<int> {1, 22, 3, 4}; 
    var func = new Action<int>(itemToAdd => listBox1.Items.Add(itemToAdd)); 
    foreach (var item in itemList) 
    { 
     listBox1.Invoke(func, item); 
    } 
} 

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

  • कोई संबंधित समस्या नहीं^_^