Seite 1 von 1

Programm läuft, aber Fenstertitel zeigt (Keine Rückmeldung)

Verfasst: 27.05.2016 13:34
von kartmanne
HI,

mein Projekt ist schon inzwischen sehr umfangreich, so dass ich die code-schnipsel erst nach Fingerzeig rausfiesel möchte, um schlicht Platz hier zu sparen :-)

Deshalb erst einmal kurz zum Problem:

Aus einem aktiven Fenster (im Vordergrund) rufe ich per Button eine Routine auf, die im aktiven Fenster eine Statusrückmeldung in einem Text-Gadget liefert. Die Routine liest eine Datei von Festplatte ein und das Text-Gadget zeigt an, welcher Datensatz eingelesen wurde. Die Routine wird erst verlassen, wenn die Datei vollständig eingelesen wurde oder EOF erkannt wurde.

Das funktioniert. Auf meinem 1Ghz-XP-PC braucht die Routine erkennbare Zeit, 30sec ungefähr (50k Datensätze).

Wenn ich nun während dieser Zeit irgendwo hinklicke (ins aktive Fenster oder auch auf's Desktop), dann läuft die Ausgabe im Text-Gadget nicht weiter. Nach ein paar Sekunden erscheint im Fenstertitel "(... keine Rückmeldung)", die Maus wird zur Sanduhr. Im win-Task-Manager ist mein Programm mit satt 99% CPU-Last erkennbar. Ich habe dann immer abgebrochen, weil ich meinte, mein Programm läuft nicht mehr richtig oder hat einen Fehler produziert. Der Task-Manager brauchte auch so bis 5 sec. nach dem Affengriff bis er erschien.

Auf einem deutlich schnelleren WIN7-PC ist der Effekt gleich. Aber mein Programm ist hier anscheinend so schnell, dass ich erkennen konnte, dass mein Programm doch stabil läuft, bis die Routine ordnungsgemäß verlassen wird. Der optische Effekt ist fast gleich: Es kommt "(...keine Rückmeldung)" im Fenstertitel aber die Sanduhr kommt nicht. Nach Abschluss der Routine laufen WIN und mein Programm weiter fehlerfrei.

Ich habe auch eine debug-Ausgabe in die Routine eingebaut - das debug-Fenster zeigt auch keine Veränderung mehr, wenn der Effekt eintritt. Nach meine WIN7-Erfahrung hab ich das auf dem XP-PC mal "ausgesessen". Der XP-PC beendet die Routine auch ordnungsgemäß... nach so 3min. Ich habe den Eindruck, dass nur die Bildschirmausgabe unterbunden wird.

Wie kann ich diesen für den Benutzer kritisch erscheinenden Effekt wegbekommen? Es würde mir reichen, wenn das Text-Gadget weiterhin die Ausgaben machen würde. Ich habe stickywindow und setactivateWindow direkt vor und nach der Routine benutzt, es ändert sich nix am Effekt.

Re: Programm läuft, aber Fenstertitel zeigt (Keine Rückmeldu

Verfasst: 27.05.2016 13:41
von RSBasic
Wird der Lese-Vorgang in deiner Ereignisschleife deines Fensters durchgeführt? Wenn innerhalb deiner Ereignisschleife ein Vorgang durchgeführt wird, der etwas länger dauert, dann wird deine Schleife gestoppt und es können keine weiteren Fensterevents empfangen werden. Dann hast du das Problem, dass Windows sagt, dass das Fenster nicht mehr reagiert.
Am besten solche zeitintensive Vorgänge woanders auslagern, so dass es eventunabhängig läuft. Z.B. in Threads.
Dann hast du auch nicht das Problem, dass dein Fenster nicht mehr reagiert und du kannst trotzdem weiterhin die Gadgets benutzen.

Re: Programm läuft, aber Fenstertitel zeigt (Keine Rückmeldu

Verfasst: 27.05.2016 14:39
von kartmanne
HI,
ja, es gibt eine Ereignisschleife, die halt alle Buttons, Mausklicks, etc. (aller Fenster) abfragt (Waitwindowsevent). Diese Schleife hat auch zwei timer, die jedoch nicht an dieses Fenster gebunden sind.
Ja, die routine muß erst beendet werden, bevor die Ereignisschleife wieder betreten wird.

ok. die erklärung leuchtet mir ein. Dass Windows dies so behandelt war mir nicht bekannt. Danke.

Re: Programm läuft, aber Fenstertitel zeigt (Keine Rückmeldu

Verfasst: 27.05.2016 15:23
von udg
eine Frage:

Code: Alles auswählen

Waitwindowsevent()
,steht das so im Code? Gibts doch gar nit. Das heisst dann

Code: Alles auswählen

WaitWindowEvent()

Code: Alles auswählen

 setactivateWindow
Das heisst dann

Code: Alles auswählen

SetActiveWindow()

Manchmal machen die Tippfehler den Unterschied.

Re: Programm läuft, aber Fenstertitel zeigt (Keine Rückmeldu

Verfasst: 20.06.2016 12:29
von DarkSoul
Das passiert, wenn ein Programm nicht mit der Event-Queue hinterherkommt. Und das passiert, wenn die Abstände zwischen den WindowEvent()-Aufrufen zu groß sind.

Man muss nicht gleich n Thread machen.

Ich mache es auch mal so, wenn es was ist, wo der User ohnehin warten muss:
-Gui sperren (Fenster drüber mit Progressbar und Cancelbutton, so dass der User nicht viel machen kann)
-Alle x Schleifendurchläufe die Event-Queue abfragen, bis sie leer ist (ggf. Klick auf Abbrechen auswerten und Vorgang abbrechen). Dabei auch die Progressbar aktualisieren, damit der User sieht, dass das Programm nicht hängt.
-Gui wieder freigeben und Rückkehr in den Main-Loop

Ich würde einen Thread eher dann machen, wenn der User währenddessen weiterarbeiten können soll (Netzwerkabfrage, Update, Laden von Vorschaugrafiken...)

Threads sind aufwändiger und für Anfänger ungeeignet, da sie völlig asynchron laufen:
- gleichzeitiger Speicherzugriff auf dieselbe Stelle zwischen Thread und Hauptschleife muss verhindert werden (Mutex).
- Thread darf nicht selber auf die Gui zugreifen
- Race-Conditions möglich.
- purebasic ist in Sachen Mehrläufigkeit schlecht konzipiert (meine Meinung). In anderen Sprachen geht das leichter und deren Debugger erkennen Programmierfehler besser, die Speicherkorruption verursachen.

In blödesten Fällen stürzt das Hauptprogramm an zufälligen Stellen ab, weil der Thread durch einen Fehler den Speicher durcheinander gebracht hat. Ursache schwer auffindbar.