Delphi-PRAXiS

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)

Kathmai 11. Apr 2014 12:53

Programm mit Zugriffsverletzung - 1. PC funktioniert - 2. Nicht
 
Hallo Leute,

hab ein kleines Problem. Habe das Firemonkey Sample "FlipViewDemo" etwas abgeändert. Funktioniert soweit aber auf dem Entwicklungs PC läuft es beim Laden der Bilder ohne Probleme.
Auf dem PC wofür das Programm bestimmt ist, kommt eine Zugriffsverletzung und zwar in Form von "Zugriffsverletzung bei Adresse .....A14554 in Modul 'ScreenPlayer.exe'. Lesen von Adresse 0000000000000000".

Die Bilder werden von einem Ordner geladen (JPEG's) und im Sample Programm in einem Thread geladen im Hintergrund.

Auf dem Entwicklungs-PC läuft alles Problemlos auf dem anderen kommt der Fehler. - Selben Bilder und Anzahl wird verwendet.

2. PC wo die Zugriffsverletzung kommt: Zotac nano AQ-01 mit Samsung EVO 120 GB und 4GB RAM - CPU AMD A4-5000

- Beides Win7 Pro 64Bit

Debuggen kann ich auch nicht da Delphi den Prozess nicht "erzeugen" kann. Hab schon Delphi mit admin Rechten gestartet aber bringt auch nix. Kann das Programm nur ohne Debugger zum laufen kriegen.

Hat jemand eine Ahnung woran das liegen könnte?

Hier die Ladefunktion (nichts verändert gegenüber des Samples von Embarcadero).

Delphi-Quellcode:
procedure TImageDataSource.Load;

var
  SR: TSearchRec;
  Res: Integer;
  I: Integer;
  ImagesFilter: string;
begin
  I := 0;

  // Find all images
  ImagesFilter := ImagesPath + '*.jpg';
  Res := FindFirst(ImagesFilter, faAnyFile, SR);
  while Res = 0 do
  begin
    SetLength(FImages, I + 1);
   try
    FImages[I] := TBitmap.CreateFromFile(ImagesPath + SR.Name);
   except
    showmessage('Fehler');
   end;
    Res := FindNext(SR);
    Inc(I);
  end;
  if Length(FImages) > 0 then
    FCurrentIndex := 0
  else
    FCurrentIndex := -1;
end;
Danke im vorraus!

DeddyH 11. Apr 2014 13:16

AW: Programm mit Zugriffsverletzung - 1. PC funktioniert - 2. Nicht
 
Ich hab zwar von FM keinen Plan, aber bist Du sicher, dass der Fehler im geposteten Code auftritt? Die Speicheradresse lässt ja eher einen Null-Poiter-Zugriff vermuten, dafür kann ich im gezeigten Code keine Möglichkeit erkennen.

Blup 11. Apr 2014 14:35

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

Zitat von Kathmai (Beitrag 1255337)
Habe das Firemonkey Sample "FlipViewDemo" etwas abgeändert.
...
Hat jemand eine Ahnung woran das liegen könnte?
...
Hier die Ladefunktion (nichts verändert gegenüber des Samples von Embarcadero).

Der erste April ist vorbei. ;)

himitsu 11. Apr 2014 17:50

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

Debuggen kann ich auch nicht da Delphi den Prozess nicht "erzeugen" kann. Hab schon Delphi mit admin Rechten gestartet aber bringt auch nix. Kann das Programm nur ohne Debugger zum laufen kriegen.
Man kann das Programm auch erst starten und sich dann mit dem Debugger darauf verbinden. (siehe Menü "Start")

jaenicke 12. Apr 2014 07:08

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

Zitat von Kathmai (Beitrag 1255337)
Habe das Firemonkey Sample "FlipViewDemo" etwas abgeändert.

Zitat:

Zitat von Kathmai (Beitrag 1255337)
Hier die Ladefunktion (nichts verändert gegenüber des Samples von Embarcadero).

Statt hier copyrightgeschützten Quelltext der Firemonkey-Bibliotheken zu posten (TImageDataSource gehört ja nicht zu den Samples) (EDIT: Ok, gehört zu den Samples, hab mich verguckt...), wäre es sinnvoll zu posten was du geändert hast...

Außerdem:
Läuft denn die ursprüngliche Fassung? (Kannst du ggf. ja aus dem Repository reverten, das sollte direkt schon so eingerichtet sein.)

Dejan Vu 12. Apr 2014 07:12

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

Zitat von jaenicke (Beitrag 1255393)
Statt hier copyrightgeschützten Quelltext der Firemonkey-Bibliotheken zu posten

Ich glaube, das ist zu banal, um es als schützenswert zu erachten. Wenn ich "I'll be back" poste, bekomme ich ja auch keinen Ärger mit der GEMA (oder? :oops:)?

jaenicke 12. Apr 2014 08:34

AW: Programm mit Zugriffsverletzung - 1. PC funktioniert - 2. Nicht
 
Also bei mir kommt die Schutzverletzung auch (XE5, 32-Bit und 64-Bit Kompilat). Das passiert direct bei der Benutzung des IWICImagingFactory Interfaces in TBitmapCodecWIC.LoadFromFile in dieser Zeile:
Delphi-Quellcode:
    TCanvasD2D.ImagingFactory.CreateDecoderFromStream(SA, GUID_NULL, WICDecodeMetadataCacheOnDemand, dec);
...
Das wird in dem von dir geposteten Quelltext in TBitmap.CreateFromFile benutzt. Da kann ich so auf den ersten Blick leider auch nicht helfen, ich muss los. Ich schaue später noch einmal drauf.

himitsu 12. Apr 2014 09:42

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

Zitat von jaenicke (Beitrag 1255393)
Statt hier copyrightgeschützten Quelltext der Firemonkey-Bibliotheken zu posten

Die Demos von Delphi sind seit 5 Jahren öffentlich und für alle frei zugänglich.
radstudiodemos-code\Object Pascal\FireMonkey Desktop\MetropolisUIFlipViewDemo\FMX.FlipView.Data .pas

Es ist das Einzige, was man praktisch wöchentlich am Delphi aktualisieren kann, auch nach dem Jahr noch.
http://sourceforge.net/projects/radstudiodemos/
http://sourceforge.net/p/radstudiodemos/code/HEAD/tree/
http://docwiki.embarcadero.com/CodeE...ategory:Sample
http://docwiki.embarcadero.com/CodeE...olsDemo_Sample
http://docwiki.embarcadero.com/RADSt...Changes_for_XE
...

Wenn das Demoverzeichnis nicht bereits als SVN-Repository vorliegt, dann kann man es einfach neu auschecken.
Ansonsten mal updaten und schauen, ob es eventuell einen Bugfix gab.

jaenicke 12. Apr 2014 11:24

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

Zitat von himitsu (Beitrag 1255403)
Die Demos von Delphi sind seit 5 Jahren öffentlich und für alle frei zugänglich.
radstudiodemos-code\Object Pascal\FireMonkey Desktop\MetropolisUIFlipViewDemo\FMX.FlipView.Data .pas

Ok, ich habe mich verguckt, ich dachte die Datei wäre aus der Bibliothek von FireMonkey. :oops:

Zitat:

Zitat von himitsu (Beitrag 1255403)
Wenn das Demoverzeichnis nicht bereits als SVN-Repository vorliegt, dann kann man es einfach neu auschecken.
Ansonsten mal updaten und schauen, ob es eventuell einen Bugfix gab.

Leider nicht. Das war das erste was ich in XE5 gemacht hatte.

Harry Stahl 12. Apr 2014 13:27

AW: Programm mit Zugriffsverletzung - 1. PC funktioniert - 2. Nicht
 
Da steht aus irgendeinem Grund unter 64-Bit irgendwie die OLE-Funktionalität nicht richtig zur Verfügung.

Retten könnt Ihr es unter WIN64 so:
Delphi-Quellcode:
procedure TImageDataSource.Load;
const
  ImagesPath = './images/';
var
  SR: TSearchRec;
  Res: Integer;
  I: Integer;
  ImagesFilter: string;
begin
  oleInitialize (NIL); // HS: ADD + ActiveX to units

  I := 0;
  // Find all images
  ImagesFilter := ImagesPath + '*.jpg';
  Res := FindFirst(ImagesFilter, faAnyFile, SR);
  while Res = 0 do
  begin
    SetLength(FImages, I + 1);
    FImages[I] := TBitmap.CreateFromFile(ImagesPath + SR.Name);
    Res := FindNext(SR);
    Inc(I);
  end;
  if Length(FImages) > 0 then
    FCurrentIndex := 0
  else
    FCurrentIndex := -1;

  FindClose (sr); // HS: ADD
end;
Also ActiveX zum Uses-Abschnitt hinzu und OleInitialize in der Procedure aufrufen.
Ein Aufruf von OleInitialize zur Intialisierung der Unit reicht nicht, anscheinend gibt es irgendwo zwischendurch an anderer Stelle ein OleUnitialize.

[nur am Rande bemerkt: Findclose habe ich auch hinzugefügt, wird gerne vergessen und führt zu einer Vielzahl von Problemen]

Der Fehler tritt genau hier auf:
Delphi-Quellcode:
class function TCanvasD2D.ImagingFactory: IWICImagingFactory;
begin
  if not Assigned(FImagingFactory) then
  begin
    CoCreateInstance(CLSID_WICImagingFactory, nil, CLSCTX_INPROC_SERVER or CLSCTX_LOCAL_SERVER,
      IUnknown, FImagingFactory); // <-- Hier wird unter Win64 immer NIL zurückgeliefert, wenn OLEInitialize zuvor nicht aufgerufen wurde
  end;
  Result := FImagingFactory;
end;
Im Ergebnis steht dann also keine ImagingFactory zur Verfügung und dann kracht's eben.

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

Sir Rufo 13. Apr 2014 17:39

AW: Programm mit Zugriffsverletzung - 1. PC funktioniert - 2. Nicht
 
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.

Ja, das
Delphi-Quellcode:
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 ;)

Harry Stahl 14. Apr 2014 00:10

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

Zitat von Sir Rufo (Beitrag 1255503)
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.

Sir Rufo 14. Apr 2014 00:19

AW: Programm mit Zugriffsverletzung - 1. PC funktioniert - 2. Nicht
 
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.

Harry Stahl 14. Apr 2014 00:28

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

Zitat von Sir Rufo (Beitrag 1255520)
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...

Sir Rufo 14. Apr 2014 00:38

AW: Programm mit Zugriffsverletzung - 1. PC funktioniert - 2. Nicht
 
Um zu erkennen, warum die Bilder nicht geladen werden (bei mir werden alle 10 Bilder angezeigt), ersetz doch mal die Execute-Methode hiermit (damit werden die Exceptions aus dem Thread angezeigt):
Delphi-Quellcode:
procedure TSplashImagesLoader.Execute;
begin
  if not Assigned( Form ) or not Assigned( FImages )
  then
    Exit;

  try
    Synchronize( FForm.ShowSplashLoading );
    try
      FImages.Load;
    finally
      Synchronize( FForm.HideSplashLoading );
    end;
  except
    on E : Exception do
      Synchronize(
          procedure
        begin
          Application.ShowException( E );
        end );
  end;

end;

Harry Stahl 14. Apr 2014 00:40

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

Zitat von Sir Rufo (Beitrag 1255520)
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?

Sir Rufo 14. Apr 2014 00:43

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

Zitat von Harry Stahl (Beitrag 1255523)
Zitat:

Zitat von Sir Rufo (Beitrag 1255520)
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?

Nach meinem Verständnis verweist dann sowohl Form.FImages und FSplashImageLoader.FImages auf ein und dieselbe Instanz. Oder?

Genau die verweisen beide auf die gleiche Instanz. Die Variablen sind aber unabhängig!
Jeder dieser Variablen kann ich beliebige Werte zuweisen ohne die andere Variable zu beeinflussen.

Harry Stahl 14. Apr 2014 00:43

AW: Programm mit Zugriffsverletzung - 1. PC funktioniert - 2. Nicht
 
[QUOTE=Sir Rufo;1255522]Um zu erkennen, warum die Bilder nicht geladen werden (bei mir werden alle 10 Bilder angezeigt), ersetz doch mal die Execute-Methode hiermit (damit werden die Exceptions aus dem Thread angezeigt):

Meldung: [dcc32 Fehler] MainFrm.pas(576): E2250 Es gibt keine überladene Version von 'Synchronize', die man mit diesen Argumenten aufrufen kann.

Was muss ich ändern, damit es compiliert?

Sir Rufo 14. Apr 2014 00:45

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

Zitat von Harry Stahl (Beitrag 1255525)
Zitat:

Zitat von Sir Rufo (Beitrag 1255522)
Um zu erkennen, warum die Bilder nicht geladen werden (bei mir werden alle 10 Bilder angezeigt), ersetz doch mal die Execute-Methode hiermit (damit werden die Exceptions aus dem Thread angezeigt):

Meldung: [dcc32 Fehler] MainFrm.pas(576): E2250 Es gibt keine überladene Version von 'Synchronize', die man mit diesen Argumenten aufrufen kann.

Was muss ich ändern, damit es compiliert?


Ja, hab es schon im Beitrag geändert ;)

Harry Stahl 14. Apr 2014 00:48

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

Zitat von Sir Rufo (Beitrag 1255524)
Genau die verweisen beide auf die gleiche Instanz. Die Variablen sind aber unabhängig!
Jeder dieser Variablen kann ich beliebige Werte zuweisen ohne die andere Variable zu beeinflussen.

OK, bei genauem Nachdenken stimme ich Dir zu. Was ich meine, ist, dass diese Variablen auf ein und die gleiche Instanz verweisen und wenn ich ÜBER die unterschiedlichen Variablen in unterschiedlichen Threads auf ein- und dieselben Daten der einen Instanz zugreife, dann kann das problematisch sein.

Sir Rufo 14. Apr 2014 00:54

AW: Programm mit Zugriffsverletzung - 1. PC funktioniert - 2. Nicht
 
In Beitrag #17 sagte ich dazu:
Zitat:

Zitat von Sir Rufo (Beitrag 1255500)
@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.


Harry Stahl 14. Apr 2014 00:56

AW: Programm mit Zugriffsverletzung - 1. PC funktioniert - 2. Nicht
 
So, habe Deine Ergänzung eingebaut, es wird keine Exception geworfen, es fehlt einfach der Inhalt der letzten beiden Bilder (Die beiden Bitmaps selbst sind einfach nur NIL).

OK, glaube wir werden das heute Abend (Nacht) nicht mehr lösen. Ich nehme jetzt mal ein paar Stunden Schlaf.

Sir Rufo 14. Apr 2014 22:44

AW: Programm mit Zugriffsverletzung - 1. PC funktioniert - 2. Nicht
 
Gerade entdeckt
TThread.Synchronize() and TThread.Queue() do not work correctly in FireMonkey
Ob das hier mit reinspielt glaube ich nicht, ist aber schon peinlich ... :roll:

Harry Stahl 15. Apr 2014 19:47

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

Zitat von Sir Rufo (Beitrag 1255630)
Gerade entdeckt
TThread.Synchronize() and TThread.Queue() do not work correctly in FireMonkey
Ob das hier mit reinspielt glaube ich nicht, ist aber schon peinlich ... :roll:

Nein, daran liegt es wohl nicht, wenn man den WorkAround von Lemmy verwendet, funktioniert das Demo hier trotzdem nicht.

Das Demo funktioniert auch unter XE6 übrigens nicht!! :(

Na ja, ich will ja hier nicht meckern, bin in erster Linie jetzt mal froh um die vielen Verbesserungen und Fixes in XE6 (die Fixliste ist wirklich lang).

Erledigt ist aber leider längst noch nicht alles... Aber die Richtung stimmt. Insofern: Weiter so, EMBA:thumb:


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:47 Uhr.

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