2010-02-12 18 views
6

Dies ist meine erste Post auf dieser Website, die ich sagen muss, ist großartig!Hinzufügen eines Steuerelements in einem Formular, aus einem anderen Thread

Nun, hier ist mein Problem, und ich hoffe wirklich, dass jemand mir helfen kann.

Ich habe versucht, das Hinzufügen von Steuerelementen zu meinem Hauptformular zu verschieben, mit dem Ziel, die Startzeit zu beschleunigen. Nun laufe ich in der folgenden Ausnahme:

Cross-Thread-Betrieb nicht gültig: Control 'Form1' von einem Thread zugegriffen andere als der Faden es erstellt wurde auf.

Ich habe versucht, einfach das Problem auf ein kleineres Beispiel, aber das Problem bleibt. Hier ist mein Code:

using System; 
using System.Drawing; 
using System.Threading; 
using System.Windows.Forms; 

namespace AddConrolFromAnotherThread { 
    public partial class Form1 : Form { 

     public Form1() { 
      InitializeComponent(); 
     } 


     private void AddButton() { 
      if(this.InvokeRequired){ 
       this.Invoke(new MethodInvoker(this.AddButton)); 
      } 
      Random random = new Random(2); 
      Thread.Sleep(20); 
      Button button = new Button(); 
      button.Size = new Size(50,50); 
      button.Location = 
       new Point(random.Next(this.Width),random.Next(this.Height)); 
       this.Controls.Add(button); 
     } 

     private void buttonStart_Click(object sender, EventArgs e) { 
      Thread addControlThread = 
       new Thread(new ThreadStart(this.AddButton)); 
      addControlThread.Start(); 
     } 
    } 
} 

habe ich die Invoke-Methode verwenden, und hat zu überprüfen, ob InvokeRequiered wahr ist, aber InvokeRequiered halten „true“ zu bleiben. Das verstehe ich wirklich nicht. Zumindest würde ich StackOverflow-Ausnahme erwarten, da dies ein Rekursionsaufruf ist.

Also, wenn jemand das ähnliche Problem traf, könnten Sie mir bitte sagen, was habe ich falsch gemacht?

Danke, Igor!

Antwort

4

Das Problem in Ihrem Code ist, dass Ihre zwei Schaltflächen hinzufügen.

Setzen Sie den Code hinter dem if-Block in einen else-Block.

private void AddButton() { 
     if(this.InvokeRequired){ 
      this.Invoke(new MethodInvoker(this.AddButton)); 
     } 
     else { 
      Random random = new Random(2); 
      Thread.Sleep(20); 
      Button button = new Button(); 
      button.Size = new Size(50,50); 
      button.Location = new Point(random.Next(this.Width),random.Next(this.Height)); 
      this.Controls.Add(button); 
     } 
    } 
0

Verwenden Sie stattdessen anonyme Methoden. Erklärung ist unten.

Wenn wir Form wie dieses:

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void Form1_Load(object sender, EventArgs e) 
    { 
     Thread t = new Thread(new ThreadStart(Start)); 
     t.Start(); 
    } 

    private void UpdateText() 
    { 
     button1.Text = "New Text"; 
    } 

    void Start() 
    { 
     UpdateText(); 
    } 
} 

Dies wird eine Ausnahme werfen.

ändern Update zu:

private delegate void MyDelegate(); 

private void UpdateText() 
{ 
    if (button1.InvokeRequired) 
    { 
     button1.Invoke(new MyDelegate(UpdateText)); 
    } 
    button1.Text = "New Text"; 
} 

oder anonyme Methode verwenden:

void Start() 
{ 
    this.Invoke((MyDelegate)delegate 
    { 
     UpdateText(); 
    }); 
} 

private void UpdateText() 
{ 
    button1.Text = "New Text"; 
} 
+0

Hallo, Schärpe. Vielen Dank für eine schnelle Antwort. Aber ich bin mir nicht sicher, ob wir uns verstehen. Ich habe überprüft, ob das Formular den Call aufrufen muss. Und in meinem Fall aktualisiere ich kein Steuerelement, ich versuche nur, ein neues auf dem Formular hinzuzufügen. – Gico

+0

Der Unterschied ist nicht so groß - Sie müssen die Kontrolle erstellen, die Sie im selben Thread wie Form (nach InitializeComponent zum Beispiel) hinzufügen möchten, und dann fügen Sie es einfach aus dem separaten Thread mithilfe von Ansätzen, die ich beschrieben habe. – sashaeve

0

Es ist sehr teuer, einen Thread nur für das Hinzufügen eines Buttons zu verwenden! Benutze stattdessen den ThreadPool.

Verwandte Themen