Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi DataSet über Thread öffnen (https://www.delphipraxis.net/113713-dataset-ueber-thread-oeffnen.html)

HeikoAdams 13. Mai 2008 13:19

Datenbank: SQL Server • Version: 2000 • Zugriff über: ADO

DataSet über Thread öffnen
 
Hallo,
in meiner Anwendung habe ich einige Tabellen mit >= 1000 Datensätze, weshalb ich die Datenquellen (TAdoDataSet, TAdoQuery) in einem seperatem Thread öffnen möchte. Hierfür nutze ich die selbst geschriebene Prozedur OpenDataSource

Delphi-Quellcode:
type
  TDSOpenThread = class(TThread)
  strict private
    FConnection: TAdoConnection;
    FDataSet: TDataSet;
    procedure UpdateForms;
  protected
    procedure Execute; override;
  public
    property AdoConnection: TAdoConnection read FConnection write FConnection;
    property OpenDataSet: TDataSet read FDataSet write FDataSet;
  end;

...
OpenDataSource(FrmMain.Database, DsMaster.DataSet);
...

procedure OpenDataSource(Connection: TAdoConnection; DataSource: TDataSet);
var
  OpenThread: TDSOpenThread;
begin
  OpenThread := TDSOpenThread.Create(True);
  with OpenThread do
  begin
    AdoConnection := Connection;
    OpenDataSet := DataSource;
    Resume;
  end;

  if WaitFor(OpenThread.Handle) then
    OpenThread.Free;
end;

procedure TDSOpenThread.Execute;
begin
  if FConnection.Connected
    and not FDataSet.Active then
    FDataSet.Open;
end;

function WaitFor(Event: THandle): Boolean;
begin
  Result := False;
  while not Result do
    case MsgWaitForMultipleObjects(1, Event, False, INFINITE, QS_ALLINPUT) of
      WAIT_OBJECT_0:
        Result := True;
      WAIT_OBJECT_0 + 1:
        begin
          Application.ProcessMessages;
          if Application.Terminated then
            Exit;
        end;
    else
      RaiseLastOSError;
    end;
end;
Sobald ich jedoch eine Datenquelle mit < 100 Datensätze über diese Prozedur öffnen will, bekomme ich immer den Fehlercode 1400 "Fensterhandle ist ungültig".

Hat hier jemand ne Idee, wie ich das Problem lösen kann?

Gruß

Heiko

Bernhard Geyer 13. Mai 2008 13:34

Re: DataSet über Thread öffnen
 
Wenn ich die Zeilen mit
Delphi-Quellcode:
Application.
tritt mal wieder der von Delphi erzeugte Unit-Kommentar von TThread bezüglich Synchronisation beim Zugriff auf die VCL zu.
Fenster-Handle haben von der GDI/Win32API eine Thread-Affinität und deshalb darf nur mit diesen Fenster-Handeln im ursprünglichen (VCL-Hauptthread) gearbeitet werden.

HeikoAdams 13. Mai 2008 13:39

Re: DataSet über Thread öffnen
 
OpenDataSource wird im Hauptthread aufgerufen und im TDSOpenThread arbeite ich nicht mit Handles. WaitFor läuft ebenfalls im Hauptthread der Anwendung und sorgt dafür, das der Bildschirm nicht einfriert, wenn der Thread länger läuft.

Ich vemute, das bei kleinen Datenmengen der Thread schon fertig ist, bevor WaitFor ausgeführt wird und das es deshalb zu der Fehlermeldung kommt. Aber wie kann ich das Verhindern?

Bernhard Geyer 13. Mai 2008 13:50

Re: DataSet über Thread öffnen
 
Wieso machst du das überhaupt. ADO kann doch beim MS SQL Server selbständig die übertragung von größeren Datenmengen in einen eigenen Thread durchführen (z.B. für Grid-Anzeige).

HeikoAdams 13. Mai 2008 13:58

Re: DataSet über Thread öffnen
 
Ganz einfach: Wenn ich z.B. ein AdoDataSet mit ca. 5000 Datensätzen im Hauptthread öffne, friert während dessen die Anzeige ein und viele Kunden meinen, das Programm habe sich aufgehängt. Um das zu verhindern, wird während des Öffnen ein TAnimate angezeigt. Und damit das Animate auch unter XP ordentlich arbeitet, die (Hilfs-)Konstruktion mit dem Thread.


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:36 Uhr.

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