Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

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

CreateFile + FILE_FLAG_OVERLAPPED arbeitet nicht asynchon

  Alt 12. Nov 2007, 10:24
mir ist jetzt mal aufgefallen daß beim lesen/schreiben nichts von asynchroner Arbeitsweise zu erkennen ist. (hatte es erst für ein Debuggerproblem ghalten, also daß es nu dort nicht geht)
theoretisch sollte doch Read-/WriteFile nur den Prozess anstosen und "sofort" verlassen werden
aber es wird nachweislich erst verlassen wenn der Lese-/Schreibprozess beendet ist

hab inzwischen mehreres ausprobiert un überall das Selbe:
bei WriteFile wird gewartet
und die Warteschleife sofort beendet (da ja schon fertig gschrieben wurde)
Delphi-Quellcode:
// ohne event
ZeroMemory(@O, SizeOf(TOverlapped));

O.InternalHigh := 0; // reset OverlappedResult
O.Offset := LARGE_INTEGER(FilePos).LowPart;
O.OffsetHigh := LARGE_INTEGER(FilePos).HighPart;
WriteFile(Ho, Buffer, W2, nil, @O);
While O.Internal = STATUS_PENDING do Sleep(0);



// mit event - auto reset
ZeroMemory(@O, SizeOf(TOverlapped));
O.hEvent := CreateEvent(nil, False, False, nil);

O.InternalHigh := 0; // reset OverlappedResult
O.Offset := LARGE_INTEGER(FilePos).LowPart;
O.OffsetHigh := LARGE_INTEGER(FilePos).HighPart;
WriteFile(Ho, Buffer, W2, nil, @O);
While O.Internal = STATUS_PENDING do Sleep(0);



// mit event - manual reset
ZeroMemory(@O, SizeOf(TOverlapped));
O.hEvent := CreateEvent(nil, True, False, nil);

O.InternalHigh := 0; // reset OverlappedResult
O.Offset := LARGE_INTEGER(FilePos).LowPart;
O.OffsetHigh := LARGE_INTEGER(FilePos).HighPart;
ResetEvent(O.hEvent);
WriteFile(Ho, Buffer, W2, nil, @O);
While O.Internal = STATUS_PENDING do Sleep(0);
das öffnen und Scheiben der Daten läuft fedenfalls ohne probleme, nur daß halt an der falschen Stelle die Pause gemacht wird.

geöffnet wird die Datei so
Delphi-Quellcode:
Ho := CreateFileW(PWideChar(DestName + IntToStrF(Part + 1)), GENERIC_WRITE, FILE_SHARE_READ, nil,
  CREATE_ALWAYS, FILE_FLAG_SEQUENTIAL_SCAN or FILE_FLAG_NO_BUFFERING or FILE_FLAG_WRITE_THROUGH
  or FILE_FLAG_OVERLAPPED, 0);
Hat da zufällig noch wer einen Lösungsvorschlag?
in Google, MSDN/PSDK, Delphi ... eigentlich überall konnte ich keine anderen Varianten mehr finden.

Oder hab ich nur irgendwo überlesen, daß es mit "normalen" Dateien nicht funktioniert?

ausschitt aus meinem Program inclusive TestCode:
Delphi-Quellcode:
Var _ReadFile, _WriteFile, _Pending: Int64;
Function CPUTimeStampCounter: Int64;
ASM {$IFDEF DELPHI_5_UP} RDTSC {$ELSE} DW $310F {$ENDIF}  End;


ZeroMemory(@O, SizeOf(TOverlapped));
O.hEvent := CreateEvent(nil, False{True}, False, nil);
{} _ReadFile:=0; _WriteFile:=0; _Pending:=0;

...
{} _ReadFile:=_ReadFile-CPUTimeStampCounter;
ReadFile(Source, Buffer, W2, @W3, nil);
{} _ReadFile:=_ReadFile+CPUTimeStampCounter;

O.InternalHigh := 0; // reset OverlappedResult
O.Offset := LARGE_INTEGER(FilePos).LowPart;
O.OffsetHigh := LARGE_INTEGER(FilePos).HighPart;
//ResetEvent(O.hEvent);
{} _WriteFile:=_WriteFile-CPUTimeStampCounter;
WriteFile(Ho, Buffer, W2, nil, @O);
{} _WriteFile:=_WriteFile+CPUTimeStampCounter;
MD5Update(MD5, Buffer, W);
CRC32Update(CRC32, Buffer, W);
{} _Pending:=_Pending-CPUTimeStampCounter;
While O.Internal = STATUS_PENDING do Sleep(0);
{} _Pending:=_Pending+CPUTimeStampCounter;
If GetOverlappedResult(Ho, O, W3, True) and (W3 <> W2) Then
  Exception(612, [DestName, IntToStrF(Part + 1), LastErrorMessage]);
...

{} Exception(997, [_ReadFile, _WriteFile, _Pending);
und wie man an den Zeiten (Zahlengrößen) sieht läuft es weiterhin synchron
Zitat:
---------------------------
FileSplitter v2.0 (15)
---------------------------
3390612828
4040577155
204
---------------------------
OK
---------------------------
wäre schön wenn sich eine Lösung findet, denn ich würde gern wärend des Schweibens noch etwas machen und das ohne Multithreading
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat