AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Delphi TPicture, TJPegImage, TBitmap, TBitmap32 und Threads ...
Thema durchsuchen
Ansicht
Themen-Optionen

TPicture, TJPegImage, TBitmap, TBitmap32 und Threads ...

Ein Thema von Gausi · begonnen am 26. Sep 2019 · letzter Beitrag vom 11. Okt 2019
Antwort Antwort
Benutzerbild von Gausi
Gausi

Registriert seit: 17. Jul 2005
905 Beiträge
 
Delphi 12 Athens
 
#1

AW: TPicture, TJPegImage, TBitmap, TBitmap32 und Threads ...

  Alt 11. Okt 2019, 09:47
Ich muss hier nochmal nachfragen, weil ich die Interface-Geschichte noch nicht ganz verstanden habe, glaube ich.

Die Funktion aus dem letzten Posting (eigentlich eine private Methode einer großen Klasse, von der im Programm genau eine Instanz existiert) rufe ich mal aus einem Nebenthread auf, und mal aus dem VCL-Thread. Dabei nutze ich nicht TThread, sondern BeginThread, woraus dann die threaded Methoden aus der großen Klasse aufgerufen werden.

Um nicht jedesmal die Factory neu zu erstellen, habe ich dafür zwei private Member-Variablen in der Klasse
Delphi-Quellcode:
WICImagingFactory_VCL: IWICImagingFactory;
WICImagingFactory_ScanThread: IWICImagingFactory;
Mit IWICImagingFactory = interface(IUnknown) aus der Unit Winapi.Wincodec.


Aufgerufen wird die Methode dann über

ScalePicStreamToFile(aStream, aFilenname, 240, 240, GetProperImagingFactory(ScanMode)) Scanmode ist ein Aufzählungstyp und steuert "VCL oder Thread". Die Factory bekomme ich dann mit dieser privaten Methode, die bei Bedarf die Factory erstellt, und ansonsten die bestehende zurückliefert.

Delphi-Quellcode:
function TMyClass.GetProperImagingFactory(ScanMode: CoverScanThreadMode): IWICImagingFactory;
begin
    case ScanMode of
        tm_VCL: begin
            if WICImagingFactory_VCL = Nil then
                CoCreateInstance(CLSID_WICImagingFactory, nil, CLSCTX_INPROC_SERVER or
                    CLSCTX_LOCAL_SERVER, IUnknown, WICImagingFactory_VCL);
            result := WICImagingFactory_VCL;
        end;
        tm_Thread: begin
            if WICImagingFactory_ScanThread = Nil then
                CoCreateInstance(CLSID_WICImagingFactory, nil, CLSCTX_INPROC_SERVER or
                    CLSCTX_LOCAL_SERVER, IUnknown, WICImagingFactory_ScanThread);
            result := WICImagingFactory_ScanThread;

        end;
    end;
end;
Jetzt habe ich beim Thread das Problem, dass nach Ende des Threads die Factory nutzlos wird (sie muss wohl immer im Kontext des Threads erstellt werden, in dem sie genutzt wird). Daher muss ich die freigeben, und die Variable auf Nil setzen, damit beim nächsten Thread (es läuft aber immer nur einer nebenbei) wieder eine neue erstellt wird.

Das habe ich so gemacht
Delphi-Quellcode:
WICImagingFactory_ScanThread._Release
WICImagingFactory_ScanThread := Nil
Bei mir läuft das, bei vielen anderen knallt die Zuweisung auf Nil. So grob habe ich auch schon verstanden, warum: Wenn durch das Release der Referenzzähler Null wird, wird das Objekt dahinter freigegeben. Die Zuweisung auf Nil hingegen ruft intern wieder Release auf, aber das Objekt ist schon weg.

In der VCL-Komponente TWICImage ist diese Factory eine Class Var. Wenn ich den Code aus TWICImage.Destroy übernehme, komme ich auf
Delphi-Quellcode:
if WICImagingFactory_ScanThread._Release = 0 then
  Pointer(WICImagingFactory_ScanThread) := Nil;
Das funktioniert dann. Sehe ich das richtig, dass durch den Cast auf Pointer einfach nur die Variable auf NIL gesetzt wird, und die "Interface-Magic" dahinter nicht aktiviert wird, und somit das erreicht wird, was ich haben will? Nämlich dass das Objekt weg ist, und die Variable Nil ist?

Oder ist der ganze Ansatz kompletter Murks?
Being smart will count for nothing if you don't make the world better. You have to use your smarts to count for something, to serve life, not death.
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.074 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: TPicture, TJPegImage, TBitmap, TBitmap32 und Threads ...

  Alt 11. Okt 2019, 11:45
Das funktioniert dann. Sehe ich das richtig, dass durch den Cast auf Pointer einfach nur die Variable auf NIL gesetzt wird, und die "Interface-Magic" dahinter nicht aktiviert wird, und somit das erreicht wird, was ich haben will? Nämlich dass das Objekt weg ist, und die Variable Nil ist?
Ja!

Oder ist der ganze Ansatz kompletter Murks?
Möglich, aber man muss sich immer Raum für Verbesserung lassen. Version 2.0 wirds richten.

Warum das direkte Arbeiten mit BeginThread und kein normaler Delphi-TThread? Historische Gründe?
  Mit Zitat antworten Zitat
Benutzerbild von Gausi
Gausi

Registriert seit: 17. Jul 2005
905 Beiträge
 
Delphi 12 Athens
 
#3

AW: TPicture, TJPegImage, TBitmap, TBitmap32 und Threads ...

  Alt 11. Okt 2019, 12:50
Warum das direkte Arbeiten mit BeginThread und kein normaler Delphi-TThread? Historische Gründe?
Jep. Das Projekt dahinter ist mittlerweile im 15. Jahr und enthält einige Altlasten (begonnen mit Delphi 7, dann irgendwann der Unicode-Port zu Delphi 2009, jetzt 10.3 CE). Andere (auch alte) Teile finde ich aber immer noch "schön".

Das mit den Threads hat sich halt so entwickelt. An anderer Stelle nutze ich auch mal TThread. Besonders massive Vor- und Nachteile zwischen den beiden Varianten sehe ich nicht. Aufpassen, wenn der Thread auf den Daten arbeitet, die ggf. auch gerade angezeigt werden, muss man ohnehin.

Aber danke für die Bestätigung. Dann kann ich das so "ausliefern".
Being smart will count for nothing if you don't make the world better. You have to use your smarts to count for something, to serve life, not death.
  Mit Zitat antworten Zitat
Antwort Antwort


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 21:52 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