Autor Beitrag
HenryHux
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 542
Erhaltene Danke: 33

Windows 7 Premium
Delphi XE, Eclipse
BeitragVerfasst: Sa 06.11.10 23:28 
Moderiert von user profile iconMartok: Abgetrennt von [url=www.delphi-forum.de/...?t=102429]hier[/url]

Ok,

ich habe mit mal an dem FileMapping versucht, bin aber noch nicht weit gekommen.
Hab ein Problem, dass er mir nen Schreibfehler gibt.
Hier mal mein Prob:

OnFormCreate
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
  //MapFile erstellen falls noch nicht vorhanden
  MapHandle:= CreateFileMapping($FFFFFFFF,nil,PAGE_READWRITE,0,Sizeof(TData),MapName);
  If MapHandle > 0 then
   Begin
    //Auf den Speicherbereich zugreifen
    PData := MapViewOfFile(MapHandle,FILE_MAP_ALL_ACCESS,0,0,0);
    IF PData <> nil then
     Begin
     End
      else
       Begin
        raise exception.create('Mapfile konnte nicht geцffnet werden.');
        Close;
       End;
   End
    else
     begin
      raise exception.Create('Mapfile konnte nicht erstellt werden.');
      Close;
     end;


Der Aufruf erfolgt dann in einer Funktion:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
  function action1() : integer;
  begin
  //Daten aus der Mapfile lesen
  if pdata=nil then actioninuse:=false //falls noch kein eintrag existiert
  else actioninuse:=pdata.data1; 
    while actioninuse do //warten bis freigegeben wurde
    begin
      //Daten aus der Mapfile lesen
      actioninuse:=pdata.data1;
      showmessage('Its in use');
    end;
    //Daten in die Mapfile speichern
    PData.Data1 := false;  //beim durchlaufen mit debugger ist hier immer schluss.. wieso? passiert selbst wenn ich das progg vorher eine sekunde anhalte...
  end;


Hat jemand ne Ahnung wieso es den Fehler gibt?

Lg

Henry
HenryHux Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 542
Erhaltene Danke: 33

Windows 7 Premium
Delphi XE, Eclipse
BeitragVerfasst: Sa 06.11.10 23:44 
Ok, ich denke ich kann das Problem etwas genauer eingrenzen.
Wenn ich PData.Data1 := false; in einer normalen Prozedur benutze, ist alles ok.
Aber in einer Funktion sürzt es dann ab...
Hab aber selber keine Ahnung wieso
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19326
Erhaltene Danke: 1749

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 07.11.10 00:07 
Also was mir als erstes auffällt ist, dass du offenbar über einen Wert in der MMF versuchst die Zugriffe zu synchronisieren. Das kann nicht gut gehen.

Dafür gibt es Windows Messages usw., die reinen Daten können dann über die MMF ausgetauscht werden. (So mache ich es bei meinem Updater.)
(Eine Alternative wären Pipes, da kannst du einfach auf beiden Seiten senden und empfangen.)

Wie ist PData denn deklariert?
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: So 07.11.10 06:33 
Ein weiterer Fehler, der mir auffällt, aber nicht direkt mit deinem Problem etwas zu tun hat und wo Delphi dich auch warnen dürfte ist:

Du wirfst ERST eine Exception und versuchst dann die Resourcen freizugeben, was nie passiert, weil raise bereits die Kontrolle an den Exception Handler übergeben hat.

Außerdem: Könntest Du für die Einrückung bitte den Borland Style oder Abwandlungen davon verwenden? In der Form sieht da keiner durch ;-)

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
HenryHux Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 542
Erhaltene Danke: 33

Windows 7 Premium
Delphi XE, Eclipse
BeitragVerfasst: So 07.11.10 09:25 
Hi,

habe es jetzt so hingebastelt, dass es funktioniert - oder dass Delphi wenigstens nicht streikt.
Hier nochmal wie ichs gemacht hab:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
Type TData = Packed Record
      Data1 : boolean;
End;
  PTData = ^TData;

Const MapName = 'MyMapFile';

OnCreate
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
  //MapFile erstellen falls noch nicht vorhanden
  MapHandle:= CreateFileMapping($FFFFFFFF,nil,PAGE_READWRITE,0,Sizeof(TData),MapName);
  If MapHandle > 0 then
  Begin
    //Auf den Speicherbereich zugreifen
    PData := MapViewOfFile(MapHandle,FILE_MAP_ALL_ACCESS,0,0,0);
  end;
  pdata.data1:=false;


Funktion:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
function action1() : integer;
begin
  //Daten aus der Mapfile lesen
  if pdata=nil then actioninuse:=false
  else actioninuse:=pdata.data1;
  while actioninuse do //do nothing as long as an action is in use
  begin
    //Daten aus der Mapfile lesen
    actioninuse:=pdata.data1;
    showmessage('Its in use');
  end;
  //Daten in die Mapfile speichern
  PData.Data1 := false;
end;


Hatte noch keine Zeit es richtig zu testen, deswegen keine Ahnung ob das so klappt.
Habe aber auch meine Zweifel, wie jeanicke schon sagte, denn ich habe 4 Programme die unkontrolliert laufen.
Sprich könnten alle gleichzeitig auf die Funktion zugreifen und ich meine gelesen zu haben, dass MMF keine gleichzeitigen Zugriffe akzeptiert.
Also hätte alles was da drin is auch keine wirkliche Verbesserung gebracht...
Könnte man das eventuell noch umbauen oder muss ich mir ne total andere Methode einfallen lassen?
Solange werde ich dann schonmal über jaenickes Vorschlag nachdenken :D

Lg

Henry
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19326
Erhaltene Danke: 1749

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 07.11.10 10:43 
user profile iconHenryHux hat folgendes geschrieben Zum zitierten Posting springen:
und ich meine gelesen zu haben, dass MMF keine gleichzeitigen Zugriffe akzeptiert.
Das habe ich nie ausprobiert. Ich synchronisiere sauber, deshalb kann das bei mir auch gar nicht erst passieren. ;-)

Überlege dir aber unabhängig davon einmal am Code folgenden Ablauf:
Beide Prozesse merken parallel, dass Data1 false ist. Also kommen beide aus der while-Schleife. Jetzt schreibt der erste Data1 auf True. Jetzt ist der zweite aber schon am Check vorbei und schreibt ebenfalls Data1 auf True. Beide denken jetzt, dass sie zugreifen können...

Genau aufgrund solcher Sachen kann eine Thread- oder sogar Prozesssynchronisation auf diese Weise nicht zuverlässig klappen...
HenryHux Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 542
Erhaltene Danke: 33

Windows 7 Premium
Delphi XE, Eclipse
BeitragVerfasst: So 07.11.10 10:48 
Ok, was würdest du denn dann vorschlagen, womit ich mehrere Programme synchronisieren kann?
Mit messages kann ichs mir auch nicht wirklich gut vorstellen.
Mit MMF habe ich auch abgeschlossen, das bringt nichts :D
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19326
Erhaltene Danke: 1749

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 07.11.10 10:55 
user profile iconHenryHux hat folgendes geschrieben Zum zitierten Posting springen:
Ok, was würdest du denn dann vorschlagen, womit ich mehrere Programme synchronisieren kann?
Es gibt da viele Möglichkeiten, je nachdem was du genau machen willst.

Das hängt von den Datenmengen ab und ob diese nur teilweise geändert werden, in welcher Form die Prozesse zusammenarbeiten, ...

user profile iconHenryHux hat folgendes geschrieben Zum zitierten Posting springen:
Mit messages kann ichs mir auch nicht wirklich gut vorstellen.
Mit Messages funktioniert das gut, wenn (wie bei meinem Updater, siehe Quelltext) der Reihe nach verschiedene Prozesse auf die MMF zugreifen sollen.

Wenn im Grunde kontinuierlich Daten von einem Prozess an einen oder mehrere andere weitergegeben werden sollen, sind Pipes eine gute Variante. Denn da kann man mittels PeekNamedPipe einfach mal schauen ob Daten da sind usw.

Aber das gehört dann wieder in den ursprünglichen Thread. ;-)