Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi BeginThread, Pointer zu Form (https://www.delphipraxis.net/79911-beginthread-pointer-zu-form.html)

anse 30. Okt 2006 22:23


BeginThread, Pointer zu Form
 
Hallo,

bin seit Stunden am Rätseln über folgendes Problem:

ich habe hier eine Objekt-Methode und eine Objekt-lose Funktion. In der Objekt-Methode (1. Block) wird BeginThread die Funktion ExecQueryThread als Pointer übergeben:

Delphi-Quellcode:
function TMDIChild.StartExecQueryThread(handler: TCompletionHandler; timeout: Cardinal; window: THandle; SQLQuery: String): Cardinal;
var
  req: Cardinal;
  tp : TThreadParams;
begin
  try
    req := SetCompletionHandler(handler, timeout);
    // set up params for QueryThread
    tp := TThreadParams.Create( SQLQuery, req, self );
    result := req;
    BeginThread(nil, 0, @ExecQueryThread, @tp, 0, req);
    debug(Format('query call started for request id %d.', [req]));
  finally
  end;
end;


function ExecQueryThread( tp: Pointer ): Integer;
var
  qwe : ^TThreadParams;
  zq : TZReadOnlyQuery;
begin
  qwe := tp;
  debug('ExecQueryThread start!');
  try
    qwe.childwin.CheckConnection; <<<<<<<<< Hier knallt's mit AVs
  except
    exit;
  end;
end;

Die Struktur von TThreadParam enthält eine Eigenschaft "childwin" die ein TMDIChild enthält. Im obigen Code wird so ein Objekt erstellt mit TThreadParams.Create( SQLQuery, req, self ); Wobei "self" sich auf das TMDIChild bezieht. Ein TMDIChild ist übrigens ein Fenster mit vielen Controls und Methoden.

Delphi-Quellcode:
type
  TThreadParams = class(TObject)
    public
      query: string;
      ticket: Cardinal;
      childwin: TMDIChild;
      constructor Create(query: string; requestid: cardinal; childwin: TMDIChild);
  end;
Dieser Teil sieht eigentlich in meinen Augen ganz ok aus :) Sobald ich aber in der "function ExecQueryThread" das TThreadParams-Objekt dereferenziere und dann auf das enthaltene childwin zugreife, hagelt es Access Violations. Sporadisch klappen die Zugriffe, ich erkenne aber kein Muster bisher.

Irgendwie scheint die "childwin"-property oder das ganze TThreadParams-Objekt, in dem das childwin enthalten ist, nicht richtig dereferenziert zu werden. Oder so... Keine Ahnung. Habt ihr einen Rat?
Sorry falls ich was vergessen habe.. ich sehe schon den Wald nicht mehr...

Bernhard Geyer 31. Okt 2006 06:19

Re: BeginThread, Pointer zu Form
 
Schon mal davon gehört das man auf VCL-GUI-Komponenten nur im Hauptthread der Anwendung zugreifen darfst, das die VCL nicht Thread-Save ist :gruebel:

Und wenn du hier auf MDI-Childfenster in Threads zugreifst kracht es halt des öfteren. Wenn schon zugriff dann nur synchronisiert. Aber dann ist vermutlich bei deinem jetzigen Programmdesign der Vorteil der Threads weg.

anse 31. Okt 2006 08:49

Re: BeginThread, Pointer zu Form
 
Ui, das ist ein Super-Hinweis. Vielen Dank!

Wie mache ich das ganze denn synchronisiert?

Luckie 31. Okt 2006 09:01

Re: BeginThread, Pointer zu Form
 
Wenn die bei der WinAPI bleiben willst mit Hier im Forum suchenCriticalSections oder wenn du die Klasse TThread benutzen willst, mit der Methode Delphi-Referenz durchsuchenSynchronize

anse 1. Nov 2006 11:14

Re: BeginThread, Pointer zu Form
 
Problem gelöst:
BeginThread erwartet keinen Pointer zu TThreadParam sondern ein echtes TThreadParam, also:

FALSCH: BeginThread(blah, Addr(tp), blah)
RICHTIG: BeginThread(blah, tp, blah)

Halleluja!


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:23 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz