Delphi-PRAXiS
Seite 2 von 4     12 34      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Programm mit Zugriffsverletzung - 1. PC funktioniert - 2. Nicht (https://www.delphipraxis.net/179929-programm-mit-zugriffsverletzung-1-pc-funktioniert-2-nicht.html)

jaenicke 12. Apr 2014 16:23

AW: Programm mit Zugriffsverletzung - 1. PC funktioniert - 2. Nicht
 
Dann wäre wohl das am Ende der Unit am sinnvollsten:
Delphi-Quellcode:
initialization
  OleInitialize(nil);

finalization
  OleUninitialize;
// EDIT:
Helfen tut das bei mir allerdings nichts. Es geht nach wie vor nicht.

Kathmai 12. Apr 2014 16:26

AW: Programm mit Zugriffsverletzung - 1. PC funktioniert - 2. Nicht
 
Hallo...

Vielen Dank erstmal an Euch für die antworten.
Komisch ist nur (es werden ca. 66 JPEG's geladen) das die Fehlermeldung nur einmal kommt.

@Harry: Hab das mal so geändert wie Du es in Deinem letzten Beitrag geschrieben hast. Kann es aber erst am Montag testen da der PC wo es nicht funktioniert auf Arbeit steht.

Es sind aber beide (Entwicklungs-PC und dort wo es nicht funktioniert) Win 7 64Bit.

Dank Dir - werde am Montag mal Rückmeldung geben.

Thomas

Harry Stahl 12. Apr 2014 16:43

AW: Programm mit Zugriffsverletzung - 1. PC funktioniert - 2. Nicht
 
Zitat:

Zitat von jaenicke (Beitrag 1255438)
Dann wäre wohl das am Ende der Unit am sinnvollsten:
Delphi-Quellcode:
initialization
  OleInitialize(nil);

finalization
  OleUninitialize;
// EDIT:
Helfen tut das bei mir allerdings nichts. Es geht nach wie vor nicht.

Wobei ich ja geschrieben habe, dass es nicht funktioniert, wenn man das wie hier von Dir vorgeschlagen macht (was ich ja normalerweise auch so machen würde). Bei mir klappt es nur, wenn ich OleInitialize direkt am Anfang der Prozedur aufrufe.

jaenicke 12. Apr 2014 21:40

AW: Programm mit Zugriffsverletzung - 1. PC funktioniert - 2. Nicht
 
Entschuldigung, das habe ich überlesen.

// EDIT:
Klar, das Load wird ja in einem eigenen Thread aufgerufen...
Und OLE muss pro Thread initialisiert werden. Sprich:
Delphi-Quellcode:
procedure TSplashImagesLoader.Execute;
begin
  if not Assigned(Form) or not Assigned(FImages) then
    Exit;

  Synchronize(FForm.ShowSplashLoading);
  try
    OleInitialize(nil);
    try
      FImages.Load;
    finally
      OleUninitialize;
    end;
  finally
    Synchronize(FForm.HideSplashLoading);
  end;
end;
// EDIT2:
Ich habe es mal in die QC gepackt:
http://qc.embarcadero.com/wc/qcmain.aspx?d=124025

Harry Stahl 12. Apr 2014 23:27

AW: Programm mit Zugriffsverletzung - 1. PC funktioniert - 2. Nicht
 
Wobei ich gerade feststelle, dass nicht alle Bilder eingelesen werden, einige dazwischen sind schwarz, mitunter in zufälliger Reihenfolge.

Vorab sei noch mal bemerkt, dass in Delphi XE3 (nach meiner Meinung bislang noch die stabilste FMX-Fassung) noch alles richtig funktionierte, sowohl unter 32 als auch unter 64 bit.

Zitat:

Zitat von jaenicke (Beitrag 1255464)
Klar, das Load wird ja in einem eigenen Thread aufgerufen...
Und OLE muss pro Thread initialisiert werden. Sprich ...

Ja, so wäre es wohl richtig. Dennoch werden nicht alle Bilder gelesen, einige sind schwarz.

Erst wenn man ein Synchronize auch für die Load-Funktion hinzufügt:

Delphi-Quellcode:
Synchronize (FImages.Load);
geht es.

Was eigentlich Unsinn ist, da man Synchronize ja normalerweise nur für den Aufruf von Proceduren des Mainthreads verwendet. FImages ist aber eine lokale Thread-Variable vom Typ der Klasse "TAbstractDataSource", gehört nach meinem Verständnis also zu dem Thread "TSplashImagesLoader". Irgendwie könnte man den Verdacht bekommen, die Thread-Verwaltung funktioniert seit XE4 nicht mehr so richtig in FireMonkey. Wir hatten hier ja schon mal so ein Problem, mit Videoaufnahmen in Zusammenhang mit einem Thread, wo das alles nicht (mehr) so richtig funktionierte (Demo VideoCaptureHD)...

Es wäre schön, wenn EMBA bei einer neuen Delphi- Version einfach mal die eigenen mitgelieferten Demos testen würde, ob die noch funktionieren...

jaenicke 13. Apr 2014 16:13

AW: Programm mit Zugriffsverletzung - 1. PC funktioniert - 2. Nicht
 
Bezüglich des QC wurde um Daten zu den Systemen gebeten, da dies dort nicht reproduzierbar ist. Ich werde selbst noch mit anderen Systemen testen und dann entsprechend antworten. Könnt ihr bitte (am besten direkt im QC) auch Informationen zu euren PCs posten auf denen es geht bzw. nicht geht (Betriebssystem + Grafikkarte)?
http://qc.embarcadero.com/wc/qcmain.aspx?d=124025

Sir Rufo 13. Apr 2014 16:50

AW: Programm mit Zugriffsverletzung - 1. PC funktioniert - 2. Nicht
 
@Harry Stahl

Die Variable gehört durchaus dem Thread, da es sich bei dem Inhalt aber hier um eine Referenz zu einer Instanz handelt muss man auch die Instanz im Blick haben. Denn auf diese Instanz greift auch die Form zu.

jaenicke 13. Apr 2014 16:56

AW: Programm mit Zugriffsverletzung - 1. PC funktioniert - 2. Nicht
 
Ich habe im QC noch einiges ergänzt. Ich habe herausgefunden, dass es tatsächlich an den Threads liegen muss. Wenn ich einfach nur ein Sleep(500) vor das Load setze, brauche ich keine OLE Initialisierung. Auch auf einem älteren PC läuft es manchmal beim ersten Versuch bevor der Cache zuschlägt.

Mit dem Sleep kommen auch keinerlei Bildfehler mehr und es ging in allen Versuchen auf allen PCs.

himitsu 13. Apr 2014 17:27

AW: Programm mit Zugriffsverletzung - 1. PC funktioniert - 2. Nicht
 
Klingt irgendwie so, als wenn da etwas doch nicht ganz threadsave ist und man es demnach nicht in Threads verwenden sollte? :gruebel:

Sir Rufo 13. Apr 2014 17:35

AW: Programm mit Zugriffsverletzung - 1. PC funktioniert - 2. Nicht
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von jaenicke (Beitrag 1255501)
Ich habe im QC noch einiges ergänzt. Ich habe herausgefunden, dass es tatsächlich an den Threads liegen muss. Wenn ich einfach nur ein Sleep(500) vor das Load setze, brauche ich keine OLE Initialisierung. Auch auf einem älteren PC läuft es manchmal beim ersten Versuch bevor der Cache zuschlägt.

Mit dem Sleep kommen auch keinerlei Bildfehler mehr und es ging in allen Versuchen auf allen PCs.

Generell liegt es wohl daran, dass FMX-Framework erst komplett initialisiert sein muss, damit der Code funktioniert.
Mit einem Thread kommt es bei diesem Verhalten auf das Timing an. Ist die Framework-Initialisierung abgeschlossen bevor der Thread startet, dann ist alles gut, ansonsten kommt ein Fehler im ImageDataSoure bei
Delphi-Quellcode:
TBitmap.CreateFromFile
bzw. (mit Debug-DCUs)
Delphi-Quellcode:
function TBitmapCodecWIC.LoadFromFile(const AFileName: string;
  const Bitmap: TBitmapSurface): Boolean;
...
begin
  ...
  try
    TCanvasD2D.ImagingFactory.CreateDecoderFromStream(SA, GUID_NULL, WICDecodeMetadataCacheOnDemand, dec); // <- hier
    ...
  finally
    FS.Free;
  end;
end;
Wenn man jetzt (nur so zum Spass) einen Timer auf die Form klatscht, mit einem Interval von 1 und in diesem Timer, dann den Thread startet (anstatt im FormCreate):
Delphi-Quellcode:
procedure TFormMain.StartupTimerTimer(Sender: TObject);
begin
  StartupTimer.Enabled := False;
  // Start loading
  FSplashImageLoader.Start;
end;
dann gibt es auch keine Zugriffsverletzungen und die Bilder werden korrekt angezeigt.

Die Load-Methode habe ich auch etwas angepasst, damit bei einem Fehler nicht die ganze Hütte zusammenbricht
statt
Delphi-Quellcode:
      SetLength( FImages, I + 1 );
      FImages[I] := TBitmap.CreateFromFile( ImagesPath + SR.Name );
nehmen wir
Delphi-Quellcode:
      LBitmap := TBitmap.CreateFromFile( ImagesPath + SR.Name );
      SetLength( FImages, I + 1 );
      FImages[I] := LBitmap;
Manchmal muss man nur geschickter und sorgfältiger arbeiten und das Wesen des Frameworks verstehen (nicht wahr, E***a) :roll:

Den komplett geänderten Source habe ich mal angehängt zum Testen


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:56 Uhr.
Seite 2 von 4     12 34      

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