... wird im falschen Thread ausgeführt

broetchen

Erfahrenes Mitglied
moin

Ich habe eine Anwendung, die in zwei Threads aufgeteilt ist.

Wenn der Benutzer auf einen Button drückt, wird ein Controller angelegt und ein Thread gestartet, der eine Methode des Controllers ausführt.
Code:
private void btnGetTRY_Click(object sender, System.EventArgs e)
{
	MainController mc = new MainController();
	mc.ComputingFinished += new EventHandler(TRYComputed);
	mc.Source = this.source;

         ......
	
         Thread t = new Thread(new ThreadStart(mc.ComputeTRY));
	t.Start();

	this.Cursor = Cursors.WaitCursor;
}

Am Ende von ComputeTRY das ComputingFinished-Event geschmißen und vom Fenster abgefangen.
Code:
private void TRYComputed(object sender, EventArgs e)
{
	this.months = ((MainController)sender).Months;
	this.Cursor = Cursors.Default;

	TreeNode monthNode,dayNode;
	Month month;
	Testreferenzjahr2005.Day day;

	this.treeView1.Nodes.Clear();

	for(int i=0; i<this.months.Length; i++)
	{
		month = this.months[i];
		monthNode = new TreeNode(month.ToString());
		monthNode.Tag = month;
		for(byte j=1; j<=month.Length; j++)
		{
			day = month[j];
			dayNode = new TreeNode(day.ToString());
			dayNode.Tag = day;

			monthNode.Nodes.Add(dayNode);
		}

		this.treeView1.Nodes.Add(monthNode);
	}

	MessageBox.Show("Finished");
}

Und hier kommt jetzt folgender Fehler:
Eine nicht behandelte Ausnahme des Typs 'System.InvalidOperationException' ist in system.windows.forms.dll aufgetreten.

Zusätzliche Informationen: Der für dieses Steuerelement ausgeführte Vorgang wird vom falschen Thread aufgerufen. Marshallen Sie den richtigen Thread mit Control.Invoke oder Control.BeginInvoke, um den Vorgang auszuführen.

Mir ist leider völlig rätselhaft, was hier falsch ist.
Was ist hier schief gegangen und was muss ich machen, um es wieder zu begradigen?

mfg broetchen
 
Hallo Schwede!

Übergib dem Contoller eine Referenz auf dein Form und invoke dann darauf.
Code:
class MainController{

	Control _OwnerForm;

	void MainController( Control OwnerForm ){
		_OwnerForm = OwnerForm;
	}
	public void ComputeTRY(){
		_OwnerForm.Invoke( ComputingFinished );
	}
}
Den Thread würd ich in den Controller mit einbauen. Dann hast es absolut sauber. ;)

MfG, cosmo
 
Ich hab ne Lösung, cosmo hat mich auf eine Idee gebracht.

BeginInvoke wird einfach im Handler in der Form aufgerufen.

Code:
private delegate void ShowMonthsDelegate();
private ShowMonthsDelegate deleg;

public MainForm()
{
	this.deleg += new ShowMonthsDelegate(this.ShowMonths);
}

private void TRYComputed(object sender, EventArgs e)
{
	this.months = ((MainController)sender).Months;
	this.Cursor = Cursors.Default;

	this.BeginInvoke(this.deleg);

	MessageBox.Show("Finished");
}

private void ShowMonths()
{
	this.treeView1.Nodes.Clear();

	Month month;
	Testreferenzjahr2005.Day day;
	TreeNode monthNode, dayNode;
	for(int i=0; i<this.months.Length; i++)
	{
		month = this.months[i];

		monthNode = new TreeNode(month.ToString());
		monthNode.Tag = month;

		for(byte j=1; j<=month.Length; j++)
		{
			day = month[j];

			dayNode = new TreeNode(day.ToString());
			dayNode.Tag = day;

			monthNode.Nodes.Add(dayNode);
		}

		this.treeView1.Nodes.Add(monthNode);
	}
}

mfg broetchen
 
Zurück