Autor Beitrag
Seven of Nine
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 132
Erhaltene Danke: 1

Win XP, Win Vista HomePro
Delphi 2009
BeitragVerfasst: So 19.08.12 06:24 
Mir ist heute folgendes aufgefallen:

- Um einen internen Handler auf eine Queue von abzuarbeitenden Tasks zu schreiben, habe ich einige Variablen definiert.
Die Variablen werden dann "vorbelegt" und wenn komplettiert einem "Queue Handler" zum Abarbeiten übergeben

blos mal so als Bsp.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
type
  TADub = record
    trackID: String;
    title: String;
    SongIndex: LongInt;
    Status: Integer;
  end;

var
  ADub : Array of TADub;

//....
  SetLength(ADub, CountSelectedTitles); // set length of dynamic array
//....
  ADub[I].Status     := 0;
  ADub[I].TrackID    := Song[SongIndex].trackID;
  ADub[I].SongIndex  := SongIndex;
  ADub[I].title      := aTitle;



mein Problem: jeder Aufruf von "Application.ProcessMessages" löscht (bzw initilialisert wieder) genau die Inhalte dieser Variablen ?!?
wie ist das möglich? Was kann ich dagegen tun?


lG Martin
bummi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1248
Erhaltene Danke: 187

XP - Server 2008R2
D2 - Delphi XE
BeitragVerfasst: So 19.08.12 06:31 
An welcher Stelle im Code hast Du denn die Initialisierung eingebaut?

_________________
Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
Seven of Nine Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 132
Erhaltene Danke: 1

Win XP, Win Vista HomePro
Delphi 2009
BeitragVerfasst: So 19.08.12 06:51 
Du meinst die Definition des Records sowie die anschließende Definiton des records als DynArray ?
eigentlich so wie ich das immer mache, unterhalb
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;


(das komische ist, andere Variablen werden mir ja auch nicht überschrieben, diese aber schon)
Falsch: auch andere Varaiablen haben das gleiche problem
Es ist echt zum Haare raufen.

lG M
bummi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1248
Erhaltene Danke: 187

XP - Server 2008R2
D2 - Delphi XE
BeitragVerfasst: So 19.08.12 07:56 
nein ich meine in welchem Ereignis/Prozedur ... der Code ab Zeile 13 ausgeführt wird.

_________________
Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19339
Erhaltene Danke: 1752

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 19.08.12 09:23 
Falls es in einem Timer sein sollte, wird in Application.ProcessMessages die nächste WM_TIMER Botschaft abgearbeitet, dein Code also erneut ausgeführt.
Das Problem hättest du aber gar nicht, wenn du keine globalen Variablen / Felder verwenden würdest...
Seven of Nine Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 132
Erhaltene Danke: 1

Win XP, Win Vista HomePro
Delphi 2009
BeitragVerfasst: So 19.08.12 12:17 
Der Code (ab Zeile 13) wird innerhalb einer while schleife einer normalen Procedur (procedure TForm1.HandleConversions_Songs;
) ausgeführt, also nicht innerhalb einem Timer.

Mir ist's immer noch rätselhaft was da passiert :(

lG M
bummi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1248
Erhaltene Danke: 187

XP - Server 2008R2
D2 - Delphi XE
BeitragVerfasst: So 19.08.12 12:46 
Ein Callback einer asynchronen Komponente ...

_________________
Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19339
Erhaltene Danke: 1752

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 19.08.12 13:39 
Ok, so kommen wir nicht weiter...

Wie du das selbst herausfinden kannst ist ganz einfach:
Setze in der Routine, die einen Song behandelt drei Haltepunkte, einen in das begin, einen in die folgende Zeile, einen auf das end. Den bei begin setzt du in den Haltepunkteigenschaften (rechte Maustaste auf den Haltepunkt) in Gruppe 1. Den direkt nach dem begin setzt du dort auf Aktiviere Gruppe 1, den bei end auf Deaktiviere Gruppe 1, bei beiden nimm das Häkchen bei Anhalten raus. Dann setzt du noch einen Haltepunkt außen in der Funktion, die die while-Schleife beinhaltet, vor die Schleife und setzt dort ebenfalls auf nicht anhalten und deaktiviere Gruppe 1.

Wenn du jetzt das Programm ausführst und am zweiten Haltepunkt angehalten ankommst, bist du an einer Stelle, an der du gerade innerhalb deiner Funktion bist. Aber dennoch wird dort die Behandlung erneut aufgerufen. Nun musst du nur noch im Stacktrace schauen wo du da herkommst. ;-)
Seven of Nine Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 132
Erhaltene Danke: 1

Win XP, Win Vista HomePro
Delphi 2009
BeitragVerfasst: Mo 20.08.12 05:04 
Hi Sebastian

Puuhh, irgendwie glaube ich nicht das ich der Sache damit auf die Spur komme und vor allem nicht das ich sie damit wirklich lösen kann.
Fact ist, das einen Schritt "vor" Application.processMessages noch alles i.O. ist
und "direkt nach" Application.processMessages die Variablen initilisiert wurden

Ich glaube ich verzichte an dieser Stelle besser einfach auf Application.processMessages

lG M
DonManfred
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 148
Erhaltene Danke: 2

Windows 7
Delphi XE3 Pro + HTML5Builder
BeitragVerfasst: Mo 20.08.12 05:55 
Alternativ könntest Du auch am Anfang der Procedur timer1.enabled := false und am Ende der Procedur wieder timer1.Enabled := true setzen um zu verhindern das während der laufzeit der Procedure ein weiteres Timer-Event auftritt.

_________________
Gruss Manfred
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19339
Erhaltene Danke: 1752

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mo 20.08.12 06:28 
Also wirklich bei Application.ProcessMessages? Bist du dann vielleicht in OnIdle oder so?
Auf jeden Fall musst du aus irgendeiner Botschaftsbehandlung kommen. Woher genau kannst nur du wissen... und dementsprechend auch was man dagegen tun könnte. (Ansonsten: need more source code ;-))

Wenn du alle globalen Variablen eliminierst, wäre das vollkommen egal, ob die Methode erneut aufgerufen wird.

Jedenfalls kannst du dir ansonsten ein Flag setzen, dass du schon in der Methode drin bist, und am Anfang dies prüfen. So verhinderst du den mehrfachen Aufruf auch.
Seven of Nine Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 132
Erhaltene Danke: 1

Win XP, Win Vista HomePro
Delphi 2009
BeitragVerfasst: Mo 27.08.12 18:17 
Nach kompletter Code-Umstellung tritt das Problem nicht mehr auf.
Ich vermute das die Ursache "sich gegenseitig aufrufende Routinen" bzw. "in einem Timer" die Ursache war
wie acuh immer, vielleicht ist es interessant zu wissen das so etwas vorkommt.

lG M