AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Programm mit Zugriffsverletzung - 1. PC funktioniert - 2. Nicht

Programm mit Zugriffsverletzung - 1. PC funktioniert - 2. Nicht

Ein Thema von Kathmai · begonnen am 11. Apr 2014 · letzter Beitrag vom 15. Apr 2014
Antwort Antwort
Seite 1 von 2  1 2   
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.989 Beiträge
 
Delphi 12 Athens
 
#1

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

  Alt 13. Apr 2014, 16:13
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
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

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

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

  Alt 13. Apr 2014, 16:50
@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.
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)
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.989 Beiträge
 
Delphi 12 Athens
 
#3

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

  Alt 13. Apr 2014, 16:56
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.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.399 Beiträge
 
Delphi 12 Athens
 
#4

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

  Alt 13. Apr 2014, 17:27
Klingt irgendwie so, als wenn da etwas doch nicht ganz threadsave ist und man es demnach nicht in Threads verwenden sollte?
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

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

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

  Alt 13. Apr 2014, 17:35
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 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)

Den komplett geänderten Source habe ich mal angehängt zum Testen
Angehängte Dateien
Dateityp: zip MetropolisUIFlipViewDemo.zip (174,7 KB, 3x 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 (13. Apr 2014 um 17:37 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.561 Beiträge
 
Delphi 12 Athens
 
#6

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

  Alt 14. Apr 2014, 00:10
Generell liegt es wohl daran, dass FMX-Framework erst komplett initialisiert sein muss, damit der Code funktioniert.

...

Den komplett geänderten Source habe ich mal angehängt zum Testen
OK, habe mal Dein geändertes Projekt geladen. Das geht zwar nun ohne OLEInitialize, allerdings werden immer 3-4 Bilder nicht geladen (hast Du bei Dir auch wirklich mal alle 10 Bilder durchgeklickt, ob alle da sind und nicht einige nur schwarz sind)?

Auch wenn ich den Timer z.B. von 1 auf 100, 500, 700 erhöhe, immer fehlen Bilder.

Erst wenn ich das so ergänze, werden alle Bilder geladen.

Delphi-Quellcode:
Synchronize(FForm.ShowSplashLoading);
  try
    Synchronize(FImages.Load); // <-- Hier mit Snchronize gehts

  finally
    Synchronize(FForm.HideSplashLoading);
  end;
Ich habe gesehen, dass Du Dir die Mühe gemacht hast, überall mit einer Critical Section zu arbeiten. Das kann sonst schon eine richtige und notwendige Sache sein, aber vom Programmablauf ist das hier m.E. nicht erforderlich. Das erste Bild wird erst geladen, wenn der Bild-Lade-Thread fertig ist. Ansonsten wird immer in einfachen Events des Mainthreads auf die Bilder Zugriff genommen.

Was mir gerade auffällt: Die Mainform hat auch eine Private Eigenschaft "FImages" und im FormCreate wird diese Form-Variable dem Thread zugewiesen.

Insofern macht das zusätzliche Synchronize doch Sinn, denn letztlich wird hier im Loader-Thread doch auf eine Variable des Hauptthreads zugegriffen!

Übrigens Danke Sebastian, dass Du das mal bei QC gemeldet hast, bin gespannt, was da am Ende bei rauskommt.
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

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

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

  Alt 14. Apr 2014, 00:19
Wenn du alles was im Thread läuft synchronisiert ausführst, dann entzieht man dem Thread seine Daseinsberechtigung.

Ich werde mir das beizeiten nochmal ansehen, da ist auf jeden Fall noch was mit dem Thread los.
Diese Umsetzung des Threads finde ich auch sehr gewagt und nicht wirklich stabil.

BTW: schau mal hier http://www.delphipraxis.net/1255500-post17.html
Es wird im Übrigen nicht auf eine Variable des Hauptthreads zugegriffen, sondern beide Variablen FImages (Form, ImageDatasource) verweisen auf eine Instanz. Die Variablen sind aber unabhängig voneinander.
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 (14. Apr 2014 um 00:25 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.561 Beiträge
 
Delphi 12 Athens
 
#8

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

  Alt 14. Apr 2014, 00:28
Wenn du alles was im Thread läuft synchronisiert ausführst, dann entzieht man dem Thread seine Daseinsberechtigung.

Ich werde mir das beizeiten nochmal ansehen, da ist auf jeden Fall noch was mit dem Thread los.

Diese Umsetzung des Threads finde ich auch sehr gewagt und nicht wirklich stabil.
3 x Zustimmung! Und wie gesagt, unter XE3 funktionierte das Demo noch so, wie es soll. Ich habe auch schwer die Thread-Verwaltung in Verdacht. Hoffentlich ist das in XE6 gefixt, sonst wird es echt schwer...

Geändert von Harry Stahl (14. Apr 2014 um 00:30 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.561 Beiträge
 
Delphi 12 Athens
 
#9

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

  Alt 14. Apr 2014, 00:40
Es wird im Übrigen nicht auf eine Variable des Hauptthreads zugegriffen, sondern beide Variablen FImages (Form, ImageDatasource) verweisen auf eine Instanz. Die Variablen sind aber unabhängig voneinander.
Ja, hätte ich natürlich etwas genauer beschreiben müssen.

ABER Deine Aussage "Die Variablen sind aber unabhängig" stimmt das wirklich?

Im Oncreate der Form findet ja folgendes statt:
Delphi-Quellcode:
FImages := TImageDataSource.Create;
  // Create thread with image loader
  FSplashImageLoader := TSplashImagesLoader.Create;
  FSplashImageLoader.Form := Self;
  FSplashImageLoader.DataSource := FImages;
Nach meinem Verständnis verweist dann sowohl Form.FImages und FSplashImageLoader.FImages auf ein und dieselbe Instanz. Oder?
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

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

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

  Alt 13. Apr 2014, 17:39
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.
Ja, das OleInitialize hat nur zufälligerweise so lange gebremst, dass das Framework sich initialisieren konnte. Ist aber wohl eher ein lucky shot als ein wirklicher Fix
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)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 02:16 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