Laden...

Anwendung stellt irgendwann ihr Arbeit ein

Erstellt von inflames2k vor 13 Jahren Letzter Beitrag vor 13 Jahren 1.295 Views
inflames2k Themenstarter:in
2.298 Beiträge seit 2010
vor 13 Jahren
Anwendung stellt irgendwann ihr Arbeit ein

Hallo,

ich habe eine Anwendung die zyklisch Daten über einen Webservice abruft. - Mit den erhaltenen Daten werden Diagramme gezeichnet.

Die Anwendung funktioniert an und für sich genau so wie sie soll, doch beim Kunden kam es des öfteren dazu, dass sich über größere Zeiträume nichts getan hat obwohl deren Produktion weiter lief.

Ein Neustart der Anwendung beim Kunden führte dazu, dass auch mit den aktuellen Daten weitergearbeitet wurde & wieder die korrekte Darstellung erschien.

Ich kann das Problem zwar nachvollziehen aber finde keinen Grund dafür.

Die Anwendung ist so aufgebaut, dass innerhalb eines Threads die Daten vom Webservice abgerufen werden und mittels Invoke die Oberfläche gezeichnet wird. - Der Abruf der Daten wird durch einen Timer initialisiert.

Zuerst dachte ich daran, dass die Anwendung direkt keine Rückmeldung mehr liefert aber dem ist nicht so. - Sie friert einfach ein und macht keinen Mucks mehr.

Hat jemand eine Idee, woran das liegen könnte?

// Um noch etwas mehr ins Detail zu gehen:

Der Timer ist ein System.Windows.Forms.Timer, welcher seinen Intervall über die Appconfig bezieht. Wird das Tick Event ausgelöst, starte ich einen Thread welcher für jedes Diagramm die Daten bezieht. - Dies sind jeweils eigene Webservicemethoden und eigene Methoden in der Anwendung, für den Abruf der Daten. Sind alle Daten abgerufen (mit oder ohne Fehler) werden die Daten an UserControls übergeben, welche das jeweilige Diagramm zeichnen. - Wurden dann alle Diagramme neugezeichnet, wird gewartet, bis der Timer erneut sein Tick-Event auslöst.

Im groben und ganzen, kann ich hier nur leider keinen Grund erkennen, warum die Anwendung komplett die Arbeit einstellt, mit komplett meine ich: Sie reagiert auf keine Eingaben und bleibt starr stehen, schiebt man ein Fenster darüber, bleiben dessen Fragmente auf der Oberfläche stehen und die Anwendung lässt sich nur über den Taskmanager schließen.

Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |

2.187 Beiträge seit 2005
vor 13 Jahren

Hallo inflames2k,

Es ist jetzt nur eine Vermutung, ohne QuellCode und so weiß ich grade nichts genaueres.

Du erstellst in Timer_Tick einen neuen Thread, bist du dir sicher, dass der "ein Tick früher" erstellter Thread schon beendet ist?

Gruß
Juy Juka

916 Beiträge seit 2008
vor 13 Jahren

Das mit dem Thread ist eine gute Idee. Ich hätte noch eine andere, bist du dir sicher das du alle Control aufrufe Synchronisiert hast, daher mit Invoke aus dem GUI Thread heraus ausgeführt hast?

Desweiteren würde ich mal ein paar logs einbauen. Sprich immer beim tick event den Zeitstempel in eine log schreiben, und auch beim starten und beenden des Threads die Zeiten loggen. Eventuell siehst du dann schon die Überschneidungen auf die JuyJuka hingewiesen hat.

Again what learned...

inflames2k Themenstarter:in
2.298 Beiträge seit 2010
vor 13 Jahren

Mit dem Log hab ich auch schon gearbeitet, da wir standartmäßig ins Eventlog von Windows schreiben, hab ich dies für den Debugfall einfach mal eingebaut. - Invokes werden definitiv immer ausgeführt. -> Ansonsten käme es ja zu einer Exception.

Hallo JuyJuka,

der Ansatz war nicht schlecht, werde ich mal überprüfen, ich arbeite an der Stelle mit einer Boolschen Variable zum Prüfen ob der Thread läuft. - Eventuell läuft ja dort etwas schief, aber warum reagiert die Anwendung dann auf garnichts mehr?

Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |

Gelöschter Account
vor 13 Jahren

ich arbeite an der Stelle mit einer Boolschen Variable zum Prüfen ob der Thread läuft.

davon bitte den Code.

aber warum reagiert die Anwendung dann auf garnichts mehr?

möglich, das die GUI dermaßen zugespammed wird, das sie blockiert. ich vermute mal, das du bei der "boolschen variable" etwas essentielles vergessen hast.

inflames2k Themenstarter:in
2.298 Beiträge seit 2010
vor 13 Jahren

Ich nehme an mit essentiell meinst du ein lock?

Hier der Code:


private void GetDataTimer_Tick(Object sender, EventArgs e)
{
     lock(_bThreadRunning)
     {
          if(!_bThreadRunning)
          {
               _bThreadRunning = true;
               _getDataThread = new Thread(new ThreadStart(GetData));
               _getDataThread.Start();
          }
     }
}

Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |

3.170 Beiträge seit 2006
vor 13 Jahren

Hallo,

wird zwar das Problem nicht lösen, aber ein ValueType kann bzw. darf nicht für lock verwendet werden. Du brauchst in jedem Fall einen Referenztyp für das locking.

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

inflames2k Themenstarter:in
2.298 Beiträge seit 2010
vor 13 Jahren

Stimmt, das is richtig - hab dort auch nicht die boolsche Variable gelockt. - Mir fiel gerade noch etwas auf. Die Anwendung wandert auch nicht mehr in die CPU. - Sie ist einfach nur als Stumpfe Anwendung da.

Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |

49.485 Beiträge seit 2005
vor 13 Jahren

Hallo inflames2k,

den Fehler wirst du nur selber finden können. Das Stichwort Logging wurde schon genannt. Wenn die Anwendung nicht auf 100% CPU-/Kern-Last geht, spricht vieles für einen Deadlock.

herbivore

Gelöschter Account
vor 13 Jahren

Ich nehme an mit essentiell meinst du ein lock?

nein.
Ich möchte die Variablendeklaration sehen.

inflames2k Themenstarter:in
2.298 Beiträge seit 2010
vor 13 Jahren

Hallo herbivore,

das den Fehler nur ich finden kann ist mir bewusst, aber mir ging es ja um Ideen, wo ich suchen muss, da meine Überprüfungen bis zur Threaderstellung nichts brachten. Aufgrund der Antworten, konnte ich bisher zumindest schoneinmal nachvollziehen an welcher Stelle die Anwendung auf nichts mehr reagiert und das Problem beheben. - Deadlock kam mir auch in den Sinn nach den ersten Antworten.

Die Anwendung habe ich nun also soweit, dass sie weiterhin auf Eingaben reagiert. - Und so wie es den Anschein macht, scheint die Idee von JAck30lena in die richtige Richtung zu gehen. - Ist das GUI im Vordergrund passiert auf diesem nicht eine Änderung hole ich aber ein anderes Fenster in den Vordergrund und schiebe die Anwendung somit in den Hintergrund, sind später wieder aktuelle Daten da.

@JackJAck30lena

Variablendeklaration von? Der boolschen Variable?


private bool _bThreadRunning = false;

Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |

Gelöschter Account
vor 13 Jahren

AHA! Schau dir ganz dringend das Schlüsselwort "volatile" an. 😉

inflames2k Themenstarter:in
2.298 Beiträge seit 2010
vor 13 Jahren

Hachja "volatile" das wäre ein Punkt an den ich hätte direkt denken sollen.

Habe das System aber geändert, und zwar folgendermaßen:



private Thread _getDataThread;
private Object _lockObject;

void frmMainShown(Object sender, EventArgs e)
{
       _getDataThread = new Thread(new ThreadStart(GetData));
       _getDataThread.Start();
}

private void GetData()
{
    do
    {
        GetDiagrammData();
        lock(_lockObject)
        {
            Monitor.Wait(_lockObject, _appSets.RefreshIntervall);
        }
    }while(_appRunning);
}

Das ist auch der Grund warum die GUI nun weiterhin auf Eingaben reagiert und sich zumindest weiter zeichnet.

Allerdings musste ich dadurch auch feststellen, dass mindestens eine Methode sehr lang braucht. - Bei einem eingestellten Intervall von 30 Sekunden erhalte ich die Ausgabe erst nach c.a. 3 Minuten. - Aber das ist ein anderes Problem, das Hauptproblem ist ja nun ersteinmal beseitigt.

Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |