Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Datenkopie für Thread anders erzeugen (https://www.delphipraxis.net/133177-datenkopie-fuer-thread-anders-erzeugen.html)

moelski 27. Apr 2009 12:07


Datenkopie für Thread anders erzeugen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Moin !

Ok ich gebe zu der Titel ist etwas merkwürdig, aber ich wills mal erklären :wink:

Also ich habe im Anhang mal eine ganz einfache Anwendung hinzugefügt. Die macht nix anderes als per Thread ein Bild bzw. einen MemoryStream auf Platte zu speichern.
Nun muss man ja irgendwann mal den Thread einrichten und mit Daten versorgen. Das passiert hier:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var BlobThread : TTestThread;
begin
  BlobThread := TTestThread.Create();
  Image1.Picture.Bitmap.SaveToStream(BlobThread.Stream);
  BlobThread.Priority    := tpLower;
  BlobThread.Resume;
end;
Das funktioniert soweit auch alles. Allerdings läuft die Zeile ...
Delphi-Quellcode:
Image1.Picture.Bitmap.SaveToStream(BlobThread.Stream);
... ja im MainThread ab.

Und meine Frage wäre nun ob es eine Möglichkeit gibt, das dieser Teil unabhängig vom MainThread abläuft.
Denn wenn man dort mal eine größere Bilddatei mit speichern will, dann hängt der Main Thread so lange wie die Kopie erzeugt wird.

Die Anwendung ist übrigens nichts wirklich sinnvolls. Mir gehts da eher um das Prinzip.

quendolineDD 27. Apr 2009 12:14

Re: Datenkopie für Thread anders erzeugen
 
Einfach umkerhren ;-)
Bisher arbeitest du im Mainthread mit der Methode des Bildes. Übergeb doch einfach deinem Thread das Bild und arbeite in einer Funktion im Thread das speichern ab.

moelski 27. Apr 2009 12:20

Re: Datenkopie für Thread anders erzeugen
 
Moin !

Zitat:

Übergeb doch einfach deinem Thread das Bild und arbeite in einer Funktion im Thread das speichern ab.
Wie genau meinst du das? Denn ichkann aus dem Thread nicht auf die Elemente des Formulars zugreifen. Also das geht nicht:
Delphi-Quellcode:
procedure TTestThread.Execute;
begin
  PIC.Picture.Bitmap.SaveToStream(BlobThread.Stream);
  Stream.Position := 0;
  Stream.SaveToFile('Test.bmp');
end;
Wobei PIC dann folgendes wäre :
Delphi-Quellcode:
PIC := Form1.Image1;
So gehts wie gesagt nicht.

quendolineDD 27. Apr 2009 12:46

Re: Datenkopie für Thread anders erzeugen
 
Deswegen sollst du es ja übergeben und nicht einfach auf die Elemente aus dem Thread heraus zugreifen.
Denk aber daran, wenn du zB
Delphi-Quellcode:
constructor Create(const Picture : TBitmap; const Name : AnsiString);
schreibst, das du dann im Hauptthread und in dem Thread auf den gleichen Speicherbereich zugreifst. Hier würden sich Semaphore oder Mutexe gut machen.

moelski 27. Apr 2009 13:11

Re: Datenkopie für Thread anders erzeugen
 
Moin !

Ok lassen wir die Semaphore-Thematik mal eben aussen vor.

Delphi-Quellcode:
constructor TTestThread.Create(const Picture : TBitmap);
begin
  inherited Create(True);
  FreeOnTerminate := True;

  Stream := TMemoryStream.Create;
  Picture.SaveToStream(Stream);
end;

procedure TTestThread.Execute;
begin
  Stream.Position := 0;
  Stream.SaveToFile('Test.bmp');
end;

procedure TForm1.Button1Click(Sender: TObject);
var BlobThread : TTestThread;
begin
  BlobThread := TTestThread.Create(Image1.Picture.Bitmap);
  BlobThread.Priority    := tpLower;
  BlobThread.Resume;
end;
Das würde dann ja so aussehen. Soweit funktioniert das auch. Allerdings wird das Bild dennoch nicht im Thread kopiert.

moelski 27. Apr 2009 13:41

Re: Datenkopie für Thread anders erzeugen
 
Moin !

Muss mich korrigieren. So gehts:
Delphi-Quellcode:
TTestThread = class(TThread)
  private
  protected
    procedure Execute; override;
  public
    Stream     : TMemoryStream;
    Pic        : TBitmap;
    constructor Create(const Picture : TBitmap);
    destructor Destroy; override;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

constructor TTestThread.Create(const Picture : TBitmap);
begin
  inherited Create(True);
  FreeOnTerminate := True;

  Stream := TMemoryStream.Create;
  Pic := Picture;
end;

procedure TTestThread.Execute;
begin
  Pic.SaveToStream(Stream);
  Stream.Position := 0;
  Stream.SaveToFile('Test.bmp');
end;

procedure TForm1.Button1Click(Sender: TObject);
var BlobThread : TTestThread;
begin
  BlobThread := TTestThread.Create(Image1.Picture.Bitmap);
  BlobThread.Priority    := tpLower;
  BlobThread.Resume;
end;
Aber ist das dann niicht im Endeffekt das gleiche als wenn ich schreiben würde (in Execute):
Delphi-Quellcode:
Image1.Picture.Bitmap.SaveToStream(Stream);
Das führt ja nachweislich zu einem Crash.

Wo ist dann jetzt der Unterschied?

Übergebe ich so dem Create dann einen Pointer?

jfheins 27. Apr 2009 13:57

Re: Datenkopie für Thread anders erzeugen
 
Du könntest im Thread ein TBitmpa-Feld haben und beim erstellen des Threads das Bild mittels BitBlt reinkopieren ...

moelski 27. Apr 2009 14:00

Re: Datenkopie für Thread anders erzeugen
 
Moin !

Zitat:

Threads das Bild mittels BitBlt reinkopieren
Ne das ist nix.
Die Bilder sind nur zu Demo Zwecken! Das hat keinen tieferen Sinn. Damit kann man nur unkompliziert große Datenmengen erzeugen (Stichwort BMP).

moelski 27. Apr 2009 14:10

Re: Datenkopie für Thread anders erzeugen
 
Moin !

Ne also die letzte Variante geht auch nur (so denke ich mal) weil der Thread in der Programmunit definiert ist. Sobald der Thread in einer eigenen Unit ausgelagert ist klappt das Konstrukt nicht mehr.

quendolineDD 27. Apr 2009 15:25

Re: Datenkopie für Thread anders erzeugen
 
Wieso sollte das nicht funktionieren?


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:31 Uhr.
Seite 1 von 2  1 2      

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