Thema: Delphi Thread mit Form-Aufruf

Einzelnen Beitrag anzeigen

Bloodfire

Registriert seit: 17. Jun 2004
38 Beiträge
 
#1

Thread mit Form-Aufruf

  Alt 16. Mai 2005, 18:39
Hi!

Ich arbeite gerade an einem kleinen Netzwerkschach, welches auf folgendem beruht:

- Hauptform (primärer Thread) mit einer Userliste (PopUp-Menü: Privaten-Dlg öffnen / Schachbrett öffnen)

wenn nun entweder ein PrvDlg mit einem der User geöffnet werden soll, bzw. ein Schachbrett soll je ein neuer Thread ausgeführt werden. Das Problem dabei ist nun folgendes:

wenn ich FreeOnTerminate auf True stelle müsste ich mit ShowModal arbeiten, das wiederum aber die Hauptform deaktivieren würde und gegen das Prinzip des Projektes verstößt (da es simultanfähig sein sollte).

Seltsamerweise würde das mit ShowModal funktionieren, wenn ich meinen Aufruf der Schachbrettklasse direkt in den Execute-Abschnitt des Threads schreiben würde (ohne Synchronize), das widerum schlägt sich aber auf die Grafiken nieder, die dann, wenn man mit einem Fenster darüber fährt, verschwinden.

sähe dann so aus:

Delphi-Quellcode:
procedure TChessThread.Execute;
begin
   ChessBoard:=TChessBoard.Create;
   ChessBoard.Init(nil,0,0,AWidth,AHeight,APathFigures,AExtFigures,
     APathGraphics,AExtGraphics,APathFiles,ABoardIndex,AName);

   ChessBoard.ChessboardForm.ShowModal;

   ChessBoard.Free
end;
wenn ich jedoch (zugunsten der Grafik) das in eine extra Prozedur schriebe und diese synchronize (wofür das genau zuständig ist weiß ich immer noch nicht, aber ich sehe es an den Auswirkungen und in den Tuts wurde es empfohlen), sähe das so aus (und macht mein Hauptformular unzugängig):

Delphi-Quellcode:
procedure TChessThread.DoExecute;
begin
   ChessBoard:=TChessBoard.Create;
   ChessBoard.Init(nil,0,0,AWidth,AHeight,APathFigures,AExtFigures,
     APathGraphics,AExtGraphics,APathFiles,ABoardIndex,AName);

   ChessBoard.ChessboardForm.ShowModal;
end;

procedure TChessThread.Execute;
begin
  Synchronize(DoExecute);
end;
nun könnte ich ja diesen Code verwenden und ShowModal in Show umfunktionieren, dabei hab ich aber folgendes Problem:

da die maximale Schach-Brett Anzahl auf 5 limitiert sein soll, lasse ich außerhalb (Hauptform) eine Variable mitlaufen, welche sich bei einem Thrad Aufruf erhöht, und bei einem ThreadonTerminate-Ereignis erniedrigt (siehe: Code unten).

OnTerminate wird aber auch aufgerufen, wenn der Prozess nacher noch läuft (und nicht ge-.Free-t wurde), was dann hieße der Zähler bleibt auf 0, obwohl die Threads noch im Gange sind.

Noch dazu kommt das Problem, dass bei allen Varianten der Speicherbedarf (laut Task-Manager) immer nur ansteigt, auch wenn ich mit der ShowModal-Variante arbeite und den Speicher von meinem Schachbrett danach wieder befreie.

Woran kann das liegen?


Und eine Sache wäre dann noch: Wie kann ich überprüfen, ob mit einem der User schon ein Schachspiel läuft? (also alle aktiven Threads durchgehen?)


Hier noch der Aufrufcode (im Hauptformular):

Delphi-Quellcode:
procedure TMainAppSingle.OnPopUpItemClick(Sender: TObject);
var
  ACaption: String;
  AOppName: String;
const
  AHeight = 480;
begin
   if (UserList.ItemIndex<0)
     then exit;

   ACaption:=TMenuItem(Sender).Name;
   ACaption:=Copy(ACaption,3,length(ACaption)-2);

   AOppName:=Userlist.Items[Userlist.ItemIndex];

   if (ACaption='Chess') then
     begin
        inc(RunningChess);
        if (RunningChess>MaxThreads) then
          begin
             dec(RunningChess);
             exit;
          end
        else
          with TChessThread.Create(false,AOppName,AHeight*750 div 560,AHeight,
                 PathGraphics+'Figures\',ExtFigures,PathGraphics+'Peripher\',
                 ExtGraphics,PathFiles,2) do
            OnTerminate:=OnChessThreadClose;
     end
   else
   if (ACaption='PrvDlg') then
     begin
        inc(RunningDlgs);
        if (RunningDlgs>MaxThreads) then
          begin
             dec(RunningDlgs);
             exit;
          end
        else
          with TPrvDlgThread.Create(false,AOppName,200,300) do
            OnTerminate:=OnPrvDlgThreadClose;
     end;
end;

und zur Vervollständigung:

Delphi-Quellcode:
//--On-ChessThread-Close--------------------------------------------------------
procedure TMainAppSingle.OnChessThreadClose(Sender: TObject);
begin
   dec(RunningChess);
end;

//--On-PrvDlgThread-Close-------------------------------------------------------
procedure TMainAppSingle.OnPrvDlgThreadClose(Sender: TObject);
begin
   dec(RunningDlgs);
end;
  Mit Zitat antworten Zitat