AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi SQL-Abfrage im Thread und füllen eines ListView
Thema durchsuchen
Ansicht
Themen-Optionen

SQL-Abfrage im Thread und füllen eines ListView

Ein Thema von Captnemo · begonnen am 28. Sep 2011 · letzter Beitrag vom 29. Sep 2011
 
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#10

AW: SQL-Abfrage im Thread und füllen eines ListView

  Alt 28. Sep 2011, 23:11
Ok, hier mal ein Thread, der Datensätze an eine TListView schickt.

Der passt da noch nicht ganz für Dich (kein ZEOS, keine Query) aber das Prinzip bleibt gleich.

Daten lesen und dann immer blockweise an die ListView schicken.
so lange wie der Thread noch läuft per Queue und der letzte Abgleich erfolgt per Synchronize.
(Damit wird sichergestellt, dass alle Einträge auch die ListView ausgeliefert werden)

Delphi-Quellcode:
unit thread.SqlDataToListView;

interface

uses
  Classes,
  ComCtrls, // TListView
  DB, DBClient, // TClientDataSet
  Generics.Collections; // TList<T>

type
  TSqlDataToListViewThread = class( TThread )
  private
    FListView : TListView;
    FData : TDataSet;
  protected
    procedure SendDataToListView( AListView : TListView; AItems : TList<TStrings>; Sync : Boolean = False );
  protected
    procedure Execute; override;

  public
    constructor Create( AListView : TListView; const AFileName : string; CreateSuspended : Boolean = False );
    destructor Destroy; override;
  end;

implementation

uses
  Windows, SysUtils;

{ TGetSqlDataToListViewThread }

constructor TSqlDataToListViewThread.Create( AListView : TListView; const AFileName : string; CreateSuspended : Boolean );
begin
  inherited Create( CreateSuspended );

  FListView := AListView;
  FData := TClientDataSet.Create( nil );

  with FData as TClientDataSet do
    begin
      FileName := AFileName;
    end;
end;

destructor TSqlDataToListViewThread.Destroy;
begin
  FData.Free;
  inherited;
end;

procedure TSqlDataToListViewThread.Execute;
var
  lItems : TList<TStrings>;
  lItem : TStrings;
  lField : TField;

begin

  // Datenverbindung öffnen

  try
    FData.Open;
  except
    on E : Exception do
  end;

  if FData.Active
  then

    // Wenn die Datenverbindung gesichert hergestellt ist dann können wir ja ans Werk

    try

      lItems := TList<TStrings>.Create;
      try

        while not Terminated and not FData.Eof do

          // Wir machen hier so lange, bis ...
          // ... der Thread abgebrochen wird
          // ... oder alle Datensätze gelesen wurden

          begin

            // Daten in einen Puffer schieben

            lItem := TStringList.Create;
            for lField in FData.Fields do
              begin
                lItem.Add( lField.AsString );
              end;

            lItem.Add( DateTimeToStr( now ) );

            // Daten in die Sammelliste schreiben

            lItems.Add( lItem );

            // Nächster Datensatz
            FData.Next;

            // Wir tun mal so, als ob das hier gaaaanz lange dauert
            Sleep( Random( 15 ) );


            if ( lItems.Count >= 10 ) or Terminated or FData.Eof
            then

              // Wenn der Block voll ist,
              // oder der Thread abgebrochen wurde
              // oder keine Daten mehr zu lesen sind
              // dann die Daten an das ListView ausliefern

              SendDataToListView( FListView, lItems, Terminated or FData.Eof );

          end;

      finally
        lItems.Free;
      end;

    finally
      FData.Close;
    end;
end;

procedure TSqlDataToListViewThread.SendDataToListView( AListView : TListView; AItems : TList<TStrings>; Sync : Boolean );
var
  lItems : TObjectList<TStrings>; // Mal hier schnell geändert, sonst haben wir da ein Speicherleck :o)
  lItem : TStrings;
begin
  if MainThreadID = GetCurrentThreadId
  then

    // Ei jo, wenn wir uns jetzt im MainThread-Kontext befinden,
    // dann können wir ja wieder ganz gemütlich auf das VCL-Gedöns zugreifen

    begin

      if Assigned( AItems )
      then
        begin

          AListView.Items.BeginUpdate;
          try

            for lItem in AItems do
              begin
                with AListView.Items.Add do
                  begin
                    Caption := lItem[0];
                    lItem.Delete( 0 );
                    SubItems.Assign( lItem );
                    SubItems.Add( DateTimeToStr( now ) );
                    SubItems.Add( BoolToStr( Sync, True ) );
                  end;
              end;

          finally
            AListView.Items.EndUpdate;
          end;

          AItems.Free; // ** Hier ist das Free, und ...
        end;

    end
  else
    begin

      // Kopieren der übergebenen Daten-Liste
      lItems := TObjectList<TStrings>.Create; // ** ... hier das Create ... verkehrte Welt :o)
      for lItem in AItems do
        begin
          lItems.Add( lItem );
        end;

      // übergebene Daten-Liste leeren (da schreibt der Thread ja wieder neue Daten rein)
      AItems.Clear;

      // Jetzt rufen wir uns selber nochmal auf, aber ...
      // 1. mit der kopierten Liste
      // 2. im MainThread-Kontext (Synchronized oder Gequeued)

      if Sync
      then
        Synchronize( procedure begin SendDataToListView( AListView, lItems, Sync ); end )
      else
        Queue( procedure begin SendDataToListView( AListView, lItems, Sync ); end );
    end;
end;

end.
Im Anhang ScreenShot, Exe-Datei und der gesamte Source
Angehängte Grafiken
Dateityp: png ThreadGetSqlData_S1.png (58,2 KB, 43x aufgerufen)
Angehängte Dateien
Dateityp: zip ThreadGetSQLData.zip (834,1 KB, 37x aufgerufen)
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)

Geändert von Sir Rufo (28. Sep 2011 um 23:25 Uhr)
  Mit Zitat antworten Zitat
 


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:08 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