Hallo zusammen ich hab mal eine Frage zu C#. Mein Main Programm erstellt eine Klasse welche wiederum einen eigenen Task aufmacht. Der Task ändert bei bestimmten Ereignissen eine Variable in der Klasse. Soweit so gut. Nun wollte ich aus der Klasse eine Funktion des Hauptprogramm aufrufen um die Anzeige zu ändern, leider hab ich keinen Plan wie das geht und wollte mal fragen ob ihr mir einen Tipp geben könnt (weiß leider auch nicht wonach ich genau googlen sollte :| ) Danke und VG Tom
Ich hoffe dein Programm erstellt ein Objekt einer Klasse ;) Wenn der Task eine Klassenvariable ändert, dann integrierst du die Überwachung entweder in die Klasse mit rein oder du erstellst eine globale Überwachung dieser Variable. Gibt es nur 1 Objekt dieser Klasse, dann könntest du sie als static-Variable deklarieren (für Punkt 2 geeignet). Wenn mehrere unabhängige Objekte erstellt werden, so würde ich es in die Klasse selbst integrieren. Wie ändert der Task die Variable? Direkt in dieser oder ähnlicher Form: class_object.var = XX; oder ruft der Task eine Methode der Klasse auf, die so sein könnte: class_object.changeVar(newXX); Ich würde es über eine Methode realisieren und dann in der Methode diese Überprüfung reinsetzen Um aus der Klasse heraus Methoden des Hauptprogrammes anzusteuern könntest du die Methoden public machen oder einfach static mit Parameterübergabe: hauptklasse.machewas(param); hier macht dann machewas(param) genau das was du ändern möchtest und erhält die Parameter, die geändert werden sollen
Hallo Werkstudent, ich habe eine Klasse erstellt welche in meinen Programm als neue instanz erstellt wird:
1 | SW_Simulation_Class sw_Simulation_Class = new SW_Simulation_Class (); |
in der Klasse nutze ich eine Timer, welcher bei einem Tick Variablen ändert (bzw nicht jedesmal). Dazu hab ich eine Funktion in der Klasse welche die Änderung anzeigt
1 | protected void OnChanged(EventArgs ea) |
in meinem Hauptprogramm hab ich einen EventHandler eingebaut:
1 | sw_Simulation_Class .Changed += new EventHandler(SimulationChanged); |
und eine Funktion erstellt:
1 | public void SimulationChanged(Object objSender, EventArgs e) |
2 | {
|
3 | Ch1ProgressBar.Value = 44; |
4 | }
|
und bei dem Aufruf "Ch1ProgressBar.Value = 44;" sturzt mein program immer ab und ich bekomme eine Error Meldung (siehe Bild) Danke für eure Hilf, VG Tom
mit
1 | try
|
2 | {
|
3 | Ch1ProgressBar.Value = 44; |
4 | }
|
5 | catch (Exception exc) |
6 | {
|
7 | Console.WriteLine(Convert.ToString(exc)); |
8 | }
|
bekomme ich folgende Fehlermeldung:
1 | System.InvalidOperationException: Ungültiger threadübergreifender Vorgang: Der Zugriff auf das Steuerelement Ch1ProgressBar erfolgte von einem anderen Thread als dem Thread, für den es erstellt wurde. |
2 | bei System.Windows.Forms.Control.get_Handle() |
3 | bei System.Windows.Forms.Control.SendMessage(Int32 msg, Int32 wparam, Int32 lparam) |
4 | bei System.Windows.Forms.ProgressBar.UpdatePos() |
5 | bei System.Windows.Forms.ProgressBar.set_Value(Int32 value) |
6 | bei SW.infoGroupBox.SimulationChanged(Object objSender, EventArgs e) in C:\Users\**** \SW Form1.cs:Zeile 77. |
7 | Der Thread 0x29e0 hat mit Code 0 (0x0) geendet. |
gibt es da eine Lösung? Tom
Die Lösung heißt BeginInvoke. Siehe https://msdn.microsoft.com/de-de/library/system.windows.forms.control.begininvoke(v=vs.110).aspx
Ich habe eine Lösung gefunden
1 | public void SimulationChanged(Object objSender, EventArgs e) |
2 | {
|
3 | try
|
4 | {
|
5 | int Ch1ValueInt = bravo_SW_Simulation_Code.Ch1; |
6 | int Ch2ValueInt = bravo_SW_Simulation_Code.Ch2; |
7 | // ... etc ...
|
8 | |
9 | Ch1ProgressBar.Invoke(new Action(() => |
10 | {
|
11 | Ch1ProgressBar.Value = Ch1ValueInt; |
12 | }));
|
13 | }
|
14 | catch (Exception exc) |
15 | {
|
16 | Console.WriteLine(Convert.ToString(exc)); |
17 | }
|
18 | }
|
gibzt es noch eine elegante Lösung wenn ich gleich mehrere Änderungen z.B. auch
1 | Ch2ProgressBar.Value = Ch2ValueInt; |
etc. ändern möchte? Danke und VG Tom
@ Sebastian E.: Danke schau ich mir gleich an, ich hab auch etwas ähnliches gefunden ;)
Du hast nicht geschrieben, ob du WinForms meinst oder WPF. In WPF ist es relativ einfach in der Verbindung von MVVM pattern.
@Dirk: Es ist WinForms (siehe Namespaces im CallStack der Exception). @Tom: Du kannst das Invoke/BeginInvoke auch auf das übergeordnete Fenster oder UserControl anwenden. Per Definition "gehören" alle Controls eines Fensters zum selben Thread. Kleiner Hinweis: Invoke wartet, bis der Delegate ausgeführt wurde (synchron) und BeginInvoke kehrt direkt zurück (asynchron).
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.