Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

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

CreateFile + FILE_FLAG_OVERLAPPED arbeitet nicht asynchon

  Alt 12. Nov 2007, 11: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
$2B or not $2B
  Mit Zitat antworten Zitat