Autor Beitrag
Vegeto
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 262



BeitragVerfasst: Mi 03.07.13 15:10 
Hallo an alle,

habe mal nur eine Frage also ich habe eine Anwendung, wo ich mit einem Timer Arbeite:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
void Timer_Tick(object sender, EventArgs e)
        {            
            if (trackBar_OnOFF.Value.ToString() == "1")
            {
                WriteTable();
            }
            else if (trackBar_OnOFF.Value.ToString() == "0")
            {
                // do somethink
            }
         }


Nun kommt bei der if stelle jedesmal dieser Fehler:
ausblenden Quelltext
1:
Ungültiger threadübergreifender Vorgang: Der Zugriff auf das Steuerelement trackBar_OnOFF erfolgte von einem anderen Thread als dem Thread, für den es erstellt wurde.					


Habe einiges nach gelesehen und habe herraus gefunden das ich das mit Invoke lösen kann, doch weiß ich nicht wie ich das verwenden soll :( :( :(

Ich hoffe jmd kann mir ein tipp geben

lg
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mi 03.07.13 15:37 
Was ist das für ein Timer? Ein Tick Event hört sich nach einem Winforms Timer an und der benutzt gar keine Threads.
Vegeto Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 262



BeitragVerfasst: Mi 03.07.13 16:16 
ups vergessen das mit zuschreiben, ist ein System.Timers.Timer also kein Winforms Timer.

ist auch kein Tick event sondern Timer.Elapsed += new ElapsedEventHandler(Timer_Tick);
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mi 03.07.13 16:46 
Zitat:
ist auch kein Tick event sondern Timer.Elapsed += new ElapsedEventHandler(Timer_Tick);

Nenn den EventHandler auch wie deinen Event und wenn möglich benutz auch die richtigen EventArgs. Sonst verwirrst du nicht nur andere sondern dich selbst auch nur unnötig.


Ich rufe hier Invoke über eine kleinen Extension Methode auf um einfach einen simplen Lambda Aufruf zu bekommen der das ganze lesbar hält.

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
void timer_Elapsed(object sender, ElapsedEventArgs e)
{            
    int trackbarValue;
    this.Invoke(() => { trackbarValue = trackBar_OnOFF.Value; }); // Nur den notwendigen Teil synchronisieren
    
    if (trackbarValue == 1)
    {
        WriteTable();  // wenn hier auch ein UI Zugriff erfolgt genauso mit Invoke kapseln. Wenn möglich nur die Teile die auch nur auf die UI zugreifen.
    }
}

public static class ExtensionsMethods
{
   public static void Invoke(this Control control, Action action)
   {
      control.Invoke((Delegate)action);
   }
}

Für diesen Beitrag haben gedankt: Vegeto
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4799
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Mi 03.07.13 19:41 
Hallo Vegeto,

aber warum verwendest du denn nicht den WinForms-Timer?
Vegeto Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 262



BeitragVerfasst: Do 04.07.13 08:19 
Hallo Ralf Jansen,

Danke für deine Codehilfe, werde sie sofort einbauen und überprüfen.

Hi Th69

ich verwende den System.Timers.Timer da dieser den Eventhalter Elapsed besitzt. Da er erst nach ablauf des Intervalles die Funktion ausführt.
Aber natürlich könnte ich auch die Winforms.Timer nutzen, doch ich habe mich im vorfeld recherchiert. Den diese Gui wird später zu einem Diens umgeändert und da haben viele geschrieben, dass die System.Timers.Timer besser geeignet wäre(für dienstanwendug) als Winform.Timer.

Also ich persönlich würde auch gerne den WinForm Timer nutzen, aber viele haben hakt diesen Timer für Dienstanwendungen empfohlen.

Lg

EDIT 08.58 :
@ Ralf Jansen, habe es genau wie du übernommen und der Fehler kommt trotzdem jetzt schon bei der Variable  int trackbarvalue;
Doch ich habe mal eine frage, dieser Fehler (Exception) kommt nur dann wenn ich in Visual Studio F10 drücke und dann die Einzelnen Prozeduren/Funktionen mir in der Anwendung angucken möchte, starte ich die Anwendung mit STRG+F5 kommt es zu einem anderen Fehler( dieser Fehler ist in der Methode WriteTable(), gehe ich davon aus da es ein SQL Fehler ist und dieser erst in der Methode verwendet wird) und ich wollte mittels F10 und F11 den Fehler in der Methode bereinigen, doch dann kommt immer dieser Fehler ! Obwohl ich das von Ralf Jansen eingefügt habe.

Lg

EDIT 09.04:
Habe nun den SQL Fehler in der Methode WriteTable() gefunden und behoben :) Wenn ich die Anwendung nun mit STRG+F5 laufen lasse kommt es zu keinem Fehler!!
Doch wenn ich wieder mit F10 und mit F11 im Programmcode stochere ( habe ein Haltepunkt bei if (trackbarValue == 1) gesetzt) kommt immer wieder dieser Fehler (Fehler: Ungültiger threadübergreifender Vorgang: Der Zugriff auf das Steuerelement trackBar_OnOFF erfolgte von einem anderen Thread als dem Thread, für den es erstellt wurde.). Ich weiß nicht woran das liegen kann.
Liegt es vielleicht daran das ich zwei Timer habe? Oder Liegt es daran das ich die GUI Eigenschaft: Double Buffered auf True gesetzt habe?

Ich danke schonmal jeden der mein problem gelesehen hat :/

Lg
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Do 04.07.13 10:52 
Wieviele Threads, Double Buffered oder sonstwas ist alles egal. Wenn die Exception geworfen wirft hast du aus einen anderen Thread als dem dem das Control gehört auf das Control zugeriffen.
Und es wird mit absoluter Sicherheit nicht beim if knallen sondern im letzten Statement davor. Wenn er beim if hält ist das nur ein kleiner Debuggerglitch das der an der eigentlich gemeinten Zeile vorbeigerutscht ist.

Wenn du es so gemacht hast wie von mir gezeigt würde ich das von dir beschriebene Verhalten fast ausschließen du hast also irgendwas anderes im Timerevent gemacht haben. Greifst du noch an anderen Stellen im Event auf die UI zu die nicht innnerhalb eines Invoke stecken?
Vegeto Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 262



BeitragVerfasst: Do 04.07.13 11:12 
Ahhh jetzt macht es klick xD

kann es daran liegen das die Trackbar in einer Groupbox ist?
Und im Elapsedevent will sie dann darauf zugreifen und deswegen wirft er mir diesen Fehler raus?

Lg
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Do 04.07.13 11:54 
Zitat:
kann es daran liegen das die Trackbar in einer Groupbox ist?


Nein. Denke nicht über den Aufbau der UI nach sondern nur über deinen Code.
Vegeto Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 262



BeitragVerfasst: Do 04.07.13 15:12 
Hi Ralf Jansen

xD was willst du damit sagen xD

kann dir gerne mein Code zu kommen lassen.

Doch solange ich mit STRG+F5 starte gibt es keine Fehler :)
und wenn in in den debug Ordner gehe und von dort aus die exe starte kommt es auch zu keinem Problem :D

Lg
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Do 04.07.13 16:08 
Zitat:
xD was willst du damit sagen xD


Das wenn es ein Problem gibt der in deinem Code liegt der von deinem Event aus ausgeführt wird und nirgendwo sonst. Schon gar nicht im generierten Code den du durch Form Zusammenbasteln im Winforms Designer erzeugt hast.

Zitat:
Doch solange ich mit STRG+F5 starte gibt es keine Fehler :)
und wenn in in den debug Ordner gehe und von dort aus die exe starte kommt es auch zu keinem Problem :D


Das sagt uns nur das die Exception irgendwo behandelt wird und darum nirgendwo aufpoppt nur der Debugger bekommt die mit sobald er attached ist. Ob das schlimm ist oder nicht kann man daraus nicht ableiten. Crossthread Exception sind aber üblicherweise nicht von der Sorte das sie stillschweigend vom System geschluckt werden. Wenn der Debugger die bemerkt gibt es mit hoher Wahrscheinlichkeit ein Problem auch wenn es ohne Debugger scheinbar funktioniert. Das ist ja das tückische bei solchen Crossthreadgeschichten das knallt halt oft nur bei jedem x.ten Versuch wenn tatsächlich mal was glichzeitig passiert.
Vegeto Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 262



BeitragVerfasst: Fr 05.07.13 08:21 
user profile iconRalf Jansen hat folgendes geschrieben Zum zitierten Posting springen:
Crossthread Exception

Es ist kein Crossthread Exception, es ist eine InvalidOperationException...
Ist das ein anderer Fehler?

lg
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Fr 05.07.13 09:57 
Nein