Frage

Asynchrone Operationen mit I / O Completion Ports zurückkehren 0 Bytes übertragen, obwohl die I / O-Operationen wie erwartet (meine Lesepuffer voll werden).

BYTE buffer[1024] = {0};
OVERLAPPED o = {0};
HANDLE file = CreateFile(
    _T("hello.txt"),
    GENERIC_READ,
    FILE_SHARE_READ,
    NULL,
    OPEN_EXISTING,
    FILE_FLAG_OVERLAPPED,
    NULL
);
HANDLE completion_port = CreateIoCompletionPort(
    file,
    NULL,
    0,
    0
);
ReadFile(
    file,
    buffer,
    1024,
    NULL,
    &o
);

In der Arbeit thread:

DWORD numBytes = 0;
LPOVERLAPPED po;
GetQueuedCompletionStatus(
    completion_port,
    &numBytes,
    0,
    &po,
    INFINITE
);
GetOverlappedResult(file, &o, &numBytes, FALSE);

Beide Funktionen geben 0 Bytes in numBytes, aber buffer füllt. Ist das erwartete Verhalten?

Danke.

War es hilfreich?

Lösung

Für GetIoCompletionPort korrekt zu arbeiten, benötigen Sie einen Nicht-Null-Zeiger auf einen ULONG_PTR angeben, für den ‚Schlüssel‘ Wert zu schreiben:

ULONG_PTR key;

GetQueuedCompletionStatus(
    completion_port,
    &numBytes,
    &key,
    &po,
    INFINITE
);

GetOverlappedResult erfolgreich nutzen zu können, ich glaube, Sie brauchen ein Ereignis Griff in der OVERLAPPED Struktur zu spezifizieren (stark in jedem Fall empfohlen):

o.hEvent = CreateEvent(NULL, FALSE, TRUE, NULL);

die zwei nacheinander aufrufen, wie Sie nicht wirklich viel erreichen nicht waren - sie beide sagen Sie über die gleichen Dinge. Obwohl, wenn Sie beide nacheinander telefonieren, müssen Sie das Ereignis ändern, ein manuelles zurückgesetzt wird durch den dritten Parameter zu ändern auf TRUE CreateEvent. Meine Vermutung ist, dass Sie nur beide versuchen, zu sehen, ob Sie eine Arbeit bekommen könnten. Alles in allem würde ich wahrscheinlich nur verwenden GetQueuedCompletionStatus, und es dabei belassen. Natürlich, werden Sie in der Regel mehr tun, als es einmal nennen und beenden. Sie nennen es normalerweise in einer Schleife, die Verarbeitung des aktuellen Puffer Sie gelesen haben, dann ReadFile ruft wieder einen weiteren Puffer von Informationen zu lesen, etwa wie folgt:

DWORD numBytes;
LPOVERLAPPED po;
while (GetQueuedCompletionStatus(completion_port, &numBytes, &key, &po, INFINITE)) {
    std::cout << "\rRead: " << numBytes; // just to show it's set correctly.
    process(buffer);
    po->offset += sizeof(buffer);
    ReadFile(file, buffer, sizeof(buffer), NULL, po);
}

Mindestens in einem Schnelltest auf meinem Rechner, dies zeigte die Anzahl des Bytes korrekt (sizeof(buffer) bis zum letzten Paket, dann die verbleibende Größe der Datei) lesen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top