![]() |
CreateFile + FILE_FLAG_OVERLAPPED arbeitet nicht asynchon
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 :shock: 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:
das öffnen und Scheiben der Daten läuft fedenfalls ohne probleme, nur daß halt an der falschen Stelle die Pause gemacht wird.
// 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); geöffnet wird die Datei so
Delphi-Quellcode:
Hat da zufällig noch wer einen Lösungsvorschlag?
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); 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:
und wie man an den Zeiten (Zahlengrößen) sieht läuft es weiterhin synchron :?
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); Zitat:
|
Re: CreateFile + FILE_FLAG_OVERLAPPED arbeitet nicht asyncho
Hast Du Dir mal die Nebenbedingungen angesehen, die MS für die gleichzeitige Verwendung von FILE_FLAG_NO_BUFFERING und FILE_FLAG_OVERLAPPED angibt? Kann ich in Deinem Post nicht sehen. Da werden ja dann nur ganze Sektoren gelesen.
Grüße, Messie |
Re: CreateFile + FILE_FLAG_OVERLAPPED arbeitet nicht asyncho
bei FILE_FLAG_OVERLAPPED weiß ich ja nicht weiter und konnte auch nichts finden was dagegensprechen sollte.
hab jedenfalls nirgend's was drüber lesen können und selbst im MSDN konnte ich mindstens einen Code finden, wo beides ungeniert zusammen verwendent wird. und FILE_FLAG_NO_BUFFERING ist schon OK, dieses funktioniert auch korrekt. es werden ganze Sektoren auselesen und die Buffer-Größe wird vorher entsprechend angepaßt. aber ich hab grad mal (da du's schon ansprichst) alles bis auf FILE_FLAG_OVERLAPPED beim Dateiöffnen weggelassen und plörtzlich sieht es anderes aus :shock: Zitat:
aber eigentlich sind die anderen Parameter absichtlich so gewählt und werden soweit benötigt (vorallem FILE_FLAG_NO_BUFFERING/FILE_FLAG_WRITE_THROUGH). und ich konnte auch bisher noch nirgendwo rauslesen, daß sich einiges davon so geenseitig behindert. Das Programm läuft auch soweit ganz gut, nur wollte ich jetzt mal auf asyncron umstellen/erweitern. [add] ok, nur FILE_FLAG_NO_BUFFERING und FILE_FLAG_OVERLAPPED behindern sich. das ist zwar beim Schreiben nicht so tragisch, aber beim Lesen wird für die Umgehung der Filechache FILE_FLAG_NO_BUFFERING benötigt, womit ich auf FILE_FLAG_NO_BUFFERING nicht verzichten kann. |
Re: CreateFile + FILE_FLAG_OVERLAPPED arbeitet nicht asyncho
Zitat:
Delphi-Quellcode:
Da wird FILE_FLAG_OVERLAPPED alleinstehend verwendet, Du wirst darauf wohl nicht verzichten können.
//aus TComPort.pas
FHandle := CreateFile( PChar('\\.\' + FPort), GENERIC_READ or GENERIC_WRITE, 0, nil, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); Grüße, Messie |
Re: CreateFile + FILE_FLAG_OVERLAPPED arbeitet nicht asyncho
also in Bezug auf Dateien ist es eigentlich recht klar/einfach (sollte es jedenfalls)
mit FILE_FLAG_SEQUENTIAL_SCAN teile ich Windows mit, daß ich die Sectoren der Datei nur der Reihe nach einlesen will ![]() wärend FILE_FLAG_RANDOM_ACCESS Windows darauf hinweißt, daß man kreuz und quer auf die Datei zugreifen möchte. durch diese Beiden Optionen kann Windows seine Verwaltung der Daten etwas optimieren, da es "weiß" wie wir zugreifen wollen. mit FILE_FLAG_NO_BUFFERING wirdmitgeteilt, daß ich die Daten direkt von der Platte lesen will und nicht eine eventuelle Kopie aus der Filecache möchte. bzw werden die eingelesenen Daten nicht in die Filecache geladen und erst danach meinem Programm übergeben. FILE_FLAG_WRITE_THROUGH weißt windows an die Daten direkt in die Datei / auf die Festplatte zu schreiben und nicht erst in der Filecache zwischischenzuspeichern und diese nicht nur nach Lust und Laune irgendwann mal auf der Platte zu kopieren tja und dank FILE_FLAG_OVERLAPPED soll die Funktion asynchron arbeiten, ReadFile und WriteFile kehren sofort zurück und warten nicht auf das Ende des Schreib-/Lesevorgangs. also die anderen Parameter sind schon für eine flüssige Abarbeitung der Aufgabe wichtig. FILE_FLAG_OVERLAPPED .. nja, in den Funktionen ist sozusagen ein schleife eingebaut, die wartet bis die gewünschten Daten im Puffer sind. tja und diese Warteschleife wollte ich mir rausverlegen, sodaß das Programm Zeit für andere Dinge hat, bevor es selber eine Warteschleife ausführt. wie schon rausgefunden kann ich beim Schreiben notfalls auf FILE_FLAG_NO_BUFFERING verzichten (jedenfalls hab ich noch keine Nebenwirkungen entdeckt), aber beim Lesen brauch ich FILE_FLAG_NO_BUFFERING schon, da sonst der RAM/die FileCache unnötig zugemüllt wird und vorallem bei großen Dateien der Prozess enorm durch die FileCache verlangsamt wird. bei meinem Rechner z.B. beim Lesen über 38 MB/s ohne FileCache gegenüber der 15 MB/s mit FileCache. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:43 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 by Thomas Breitkreuz