Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - Probleme mit TThread.Synchronize


zakoon - So 11.01.09 16:28
Titel: Probleme mit TThread.Synchronize
Hallo zusammen,

Ich habe das Problem, das Sychronize nicht (immer) funktioniert.
Bei folgendem Probe-Code wird der Thread gestartet (erhalte Meldung 'started'), aber Synchronize(UpdateIcon); scheint nicht ausgeführt zu werden (keine Meldung 'sync').
Was für mich merkwürdig ist: entferne ich die Kommentierung vor dem ShowMessage in Z. 12, scheint alles abzulaufen. Ich bekomme die Meldungen 'started', 'sync', '0:0, 1:10, 2:20 ...', 'thread started?' in dieser Reihenfolge, was korrekt wäre.

Wieso funktioniert der Code, mit diesem ShowMessage? Und wie bekomme ich ihn auch ohne diese ShowMessage zum laufen?

Vielen Dank, Zak.



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
//*****************
// im Hauptprogramm
//*****************
procedure CheckNewMails;  //  <--------- Mit dem Aufruf dieser procedure geht es los
var CheckThread: TCheckThread;
    i: integer;
begin
  CheckThread:= TCheckThread.Create(true);
  CheckThread.FreeOnTerminate:= true;
  // hier sollen später Parameter übergeben werden
  CheckThread.Resume;
  // ShowMessage('Thread started?');   //  <------ Seltsam
end;

procedure ThreadFinished(aryMailCount: TAryMailcount);
var s: string;
    i: integer;
begin
  s:= '';
  for i:= 0 to 4 do
    s:=s+IntToStr(i)+': '+IntToStr(aryMailCount[i])+'; ';
  ShowMessage(s);
end;

//*****************
// Thread
//*****************
procedure TCheckThread.Execute;
begin
  CheckMail();
end;

procedure TCheckThread.CheckMail;
var i: Integer;
begin
  ShowMessage('started');
  for i:= 0 to 4 do
    aryMailCount[i]:= i*10;
  Synchronize(UpdateIcon);
end;

procedure TCheckThread.UpdateIcon;
begin
  ShowMessage('sync');
  ThreadFinished(aryMailCount);
end;


Edit: Ach ja, deklariert ist der Thread so:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
type
  TCheckThread = class(TThread)
  private
    procedure CheckMail;
    procedure UpdateIcon;
    { Private declarations }
  protected
    procedure Execute; override;
  public
    aryMailbox: TAryMailbox;
    aryMailCount: TAryMailCount;
  end;


Moderiert von user profile iconNarses: Code- durch Delphi-Tags ersetzt


MSCH - Do 15.01.09 19:55

Imho arbeitet ShowMessage auch die Nachrichtenschleife ab. Versuchs mal mit einem Application.ProcessMessages.

:-)msch


delfiphan - Do 15.01.09 19:58

Du darfst in einem Thread kein ShowMessage machen (VCL ist nicht thread-safe). Verwende stattdessen z.B. MessageBox() oder OutputDebugString(). Beim letzteren siehst du die Ausgabe in der IDE im Message-Fenster.


MSCH - Fr 16.01.09 18:41

user profile icondelfiphan hat folgendes geschrieben Zum zitierten Posting springen:
Du darfst in einem Thread kein ShowMessage machen (VCL ist nicht thread-safe). Verwende stattdessen z.B. MessageBox() oder OutputDebugString(). Beim letzteren siehst du die Ausgabe in der IDE im Message-Fenster.


darf er doch, weil es im Synchronize() Abschnitt aufruft. Das läuft im Context des Main-Threads.
:-)msch


Xentar - Fr 16.01.09 18:58

user profile iconMSCH hat folgendes geschrieben Zum zitierten Posting springen:
user profile icondelfiphan hat folgendes geschrieben Zum zitierten Posting springen:
Du darfst in einem Thread kein ShowMessage machen (VCL ist nicht thread-safe). Verwende stattdessen z.B. MessageBox() oder OutputDebugString(). Beim letzteren siehst du die Ausgabe in der IDE im Message-Fenster.


darf er doch, weil es im Synchronize() Abschnitt aufruft. Das läuft im Context des Main-Threads.
:-)msch


Ähm, nein, tut er nicht?


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
procedure TCheckThread.Execute;
begin
  CheckMail();
end;

procedure TCheckThread.CheckMail;
var i: Integer;
begin
  ShowMessage('started');
  for i:= 0 to 4 do
    aryMailCount[i]:= i*10;
  Synchronize(UpdateIcon);
end;


MSCH - Fr 16.01.09 19:41

korrekt- die hab ich garnicht gesehen. :-/
Msch