Delphi-PRAXiS
Seite 3 von 8     123 45     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Threads und TBitmaps (https://www.delphipraxis.net/181416-threads-und-tbitmaps.html)

Sir Rufo 1. Sep 2014 15:29

AW: Threads und TBitmaps
 
Ah, war mir nicht aufgefallen, dass du nur Delphi 7 hast (du könntest das ja in dein Profil eintragen).

Das Prinzip der CriticalSections, Events und Synchronize bleibt aber gleich und kannst du fast 1:1 übernehmen. Wichtig ist einfach, dass alle Zugriffe von aussen entsprechend geschützt erfolgen.

Auch die Bitmap, die im Thread erzeugt wird, ist erst nach der Fertigstellung von aussen abrufbar. Solange kann von aussen nur das zuletzt erzeugte Bitmap abgerufen werden.

Delphi-Quellcode:
System.Generics.Collections
beinhaltet
Delphi-Quellcode:
TQueue<T>
was du anders lösen müsstest, denn Generics sind Delphi 7 nicht bekannt.

TheGroudonx 1. Sep 2014 15:30

AW: Threads und TBitmaps
 
Die neue Art sieht so aus:

Aufruf:
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin      
Paintthread := TPaintThread.create(false);
Paintthread.Image := Image1;
end;
Thread:
Delphi-Quellcode:
unit UThread;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, StdCtrls, ExtCtrls;
   
type                          
  Image = TImage;
  TPaintThread = class(TThread)



private

    Zeichenflaeche: TImage;
    MyBild : TBitmap;



    procedure zeichnen;

    procedure SetImage(const Value: TImage);

  protected

    procedure Execute; override;

  public

    constructor Create(CreateSuspended: Boolean);

    property Image: TImage read Zeichenflaeche write SetImage;

  end;





implementation





constructor TPaintThread.Create(CreateSuspended: Boolean);
begin
inherited;

MyBild := TBitmap.create;
MyBild.LoadFromFile('1.bmp');

end;    



procedure TPaintThread.Execute;
begin

 While (Terminated = False) do
 begin

 Synchronize(Zeichnen);
 sleep(1);

 end;
end;



procedure TPaintThread.Zeichnen;
begin
Zeichenflaeche.Canvas.Draw(random(50) + 1,random(50) + 1,MyBild);
end;  



procedure TPaintThread.SetImage(const Value: TImage);
begin
Zeichenflaeche := Value;
end;

end.
Das geht auch sehr gut.
Ist das in etwa so wie es richtig ist oder müssen nach wie vor Schutzoptionen wie TCriticalSection darin verwendet werden?

Sir Rufo 1. Sep 2014 15:41

AW: Threads und TBitmaps
 
Ähm, das eigentliche Zeichnen erledigt du jetzt im Kontext des Hauptthreads

Delphi-Quellcode:
Synchronize( Zeichnen );
Damit hast du rein gar nichts gewonnen ... ja, es funktioniert, aber wozu benötigst du dann einen Thread, wenn du es eh wieder im Hauptthread zeichnen lässt.

Whookie 1. Sep 2014 15:45

AW: Threads und TBitmaps
 
Zitat:

Zitat von Sir Rufo (Beitrag 1270563)
Damit hast du rein gar nichts gewonnen ... ja, es funktioniert, aber wozu benötigst du dann einen Thread, wenn du es eh wieder im Hauptthread zeichnen lässt.

Das bringt nur was wenn vor dem Synchronize eine gaaaaanze menge arbeit passiert ... "zeichnen" bezieht sich hier ja nur auf einen Blit auf den Screen (der ja eigentlich flott sein sollte)

TheGroudonx 1. Sep 2014 15:51

AW: Threads und TBitmaps
 
In der Tat passiert eine ganze Menge arbeit, das geht aus dem Beispiel jetzt nicht wirklich hervor.
Es sind viele Berechnungen und Zeichnungen, die zu einem Bild zusammengefügt werden, welches dann kopiert werden soll.
Da für jedes Bild alles neu berechnet werden muss ist ein thread sinnvoll.
Soweit ich das sehe wird nur der Synchronize-Teil von der Hauptform ausgeführt während die Berechnung des Bildes, welches später auf die Hauptform gemalt, threadsicher ist?
Oder muss beim Veränderungsvorgang wieder abgesichert werden, obwohl keine Zugriffe von der Hauptform erfolgen (was nicht sehr logisch wäre)?

Sir Rufo 1. Sep 2014 15:52

AW: Threads und TBitmaps
 
Zitat:

Zitat von Whookie (Beitrag 1270564)
Zitat:

Zitat von Sir Rufo (Beitrag 1270563)
Damit hast du rein gar nichts gewonnen ... ja, es funktioniert, aber wozu benötigst du dann einen Thread, wenn du es eh wieder im Hauptthread zeichnen lässt.

Das bringt nur was wenn vor dem Synchronize eine gaaaaanze menge arbeit passiert ... "zeichnen" bezieht sich hier ja nur auf einen Blit auf den Screen (der ja eigentlich flott sein sollte)

Aber wie soll das passieren, er übergibt dem Thread die Referenz auf die Komponente, und dazu müsste man vorher per Synchronize das Bitmap daraus holen, dann verarbeiten und dann zurückschreiben. Und immer hoffen, dass die Komponente noch da ist.

So sollte Multithreading eben gerade nicht funktionieren. Der Backgroundthread bekommt alle Informationen zum Abarbeiten als Kopie übergeben, bearbeitet das und benachrichtigt, dass er damit fertig ist. Dann kann wer auch immer sich dieses abholen.

Sir Rufo 1. Sep 2014 15:56

AW: Threads und TBitmaps
 
Zitat:

Zitat von TheGroudonx (Beitrag 1270565)
In der Tat passiert eine ganze Menge arbeit, das geht aus dem Beispiel jetzt nicht wirklich hervor.
Es sind viele Berechnungen und Zeichnungen, die zu einem Bild zusammengefügt werden, welches dann kopiert werden soll.
Da für jedes Bild alles neu berechnet werden muss ist ein thread sinnvoll.
Soweit ich das sehe wird nur der Synchronize-Teil von der Hauptform ausgeführt während die Berechnung des Bildes, welches später auf die Hauptform gemalt, threadsicher ist?
Oder muss beim Veränderungsvorgang wieder abgesichert werden, obwohl keine Zugriffe von der Hauptform erfolgen (was nicht sehr logisch wäre)?

Beim Multithreading spricht man von Threadkontext und nicht "von der Hauptform ausgeführt". Entweder es wird im MainThreadContext ausgeführt (du kannst gefahrlos auf als Form-Komponenten zugreifen) oder eben nicht. Wenn du nicht im MainThreadContext bist, kannst du per Synchronize eine Methode im MainThreadContext ausführen lassen.

TheGroudonx 1. Sep 2014 16:14

AW: Threads und TBitmaps
 
Zitat:

So sollte Multithreading eben gerade nicht funktionieren. Der Backgroundthread bekommt alle Informationen zum Abarbeiten als Kopie übergeben, bearbeitet das und benachrichtigt, dass er damit fertig ist. Dann kann wer auch immer sich dieses abholen.
Das war ja auch meine Anfangsidee. Leider funktionierte das "abholen" nicht.

Whookie 1. Sep 2014 16:19

AW: Threads und TBitmaps
 
Zitat:

Zitat von Sir Rufo (Beitrag 1270566)
Der Backgroundthread bekommt alle Informationen zum Abarbeiten als Kopie übergeben, bearbeitet das und benachrichtigt, dass er damit fertig ist. Dann kann wer auch immer sich dieses abholen.

Kommt immer auf den Anwendungsfall an, ich verstehe das Beispiel so, dass in:

Delphi-Quellcode:
procedure TPaintThread.Execute;
begin

 While (Terminated = False) do
 begin
   CalcABitmap(MyBild);  // komplexe zeichenoperation...
 Synchronize(Zeichnen);
 sleep(1);

 end;
end;
..auf eine thread-interne ressource gezeichnet wird, CalcABitmap() benötigt entspr. Zeit und - wenn fertig - wird zum mainthread context gewechselt ... und da kann das bild ja abholen wer will ... in dem beispiel wirds halt in ein TImage geblittet und somit am schirm ausgegeben ...

TheGroudonx 1. Sep 2014 16:26

AW: Threads und TBitmaps
 
Was mich nur noch verwundert ist, dass wenn ich den Thread durchsteppe, nach wie vor access-violations bzw auch einmal eine eexternalexception auftreten, während Threadeigene Bitmaps bearbeitet werden, auf die nicht von ausserhalb des Threads zugegriffen wird, welche auch 100% existieren. Dabei variiert das Tempo, in dem man zur nächsten Codezeile springen kann, stark, was normalerweise nicht passiert.


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:29 Uhr.
Seite 3 von 8     123 45     Letzte »    

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