(MSDN) Занимает много времени для фонового прохождения цикла (ReadFile, WriteFile, Перекрывающаяся структура) - PullRequest
0 голосов
/ 03 июля 2018

Моя цель - прочитать DataBuffer из A и многократно записывать данные на устройство B с помощью API-интерфейсов MSDN. Я использую ReadFileEx и WriteFileEx для запроса перекрывающегося чтения и записи ввода / вывода, так что первоначальный трудоемкий цикл for, использующий ReadFile и WriteFile, теперь может идти в фоновом режиме, а основной поток пользовательского интерфейса может реагировать все время.

Сначала я создаю структуру MY_OVERLAPPED, которая наследуется от OVERLAPPED, и добавляются еще два элемента, событие - это указатель на MyClass, который может помочь получить доступ к переменным в этом классе, дескрипторы, dataBuffer и т. Д., А счетчик - для сброса значения смещения каждый время до вызова ReadFileEx. Позиция чтения - это число * 524288, так как я каждый раз считываю 524288 байтов и сохраняю в dataBuffer.

Мой вопрос: 1. как мне не использовать элемент Offset унаследованной структуры OVERLAPPED для изменения позиции чтения, например, при использовании счетчика ссылок?

2. Следующий код не работает так, как я думаю. ReadCompletionRoutine может быть запущен только один раз и в итоге получит чрезвычайно длинный номер смещения. Сейчас я предполагаю, что это проблема, и сосредоточусь на ней в первую очередь, поэтому, пожалуйста, не стесняйтесь исправлять любую структуру моего кода.

Мой поток кода: 1. установить точку чтения на 0 2. вызвать перекрытый ReadFileEx 3. Будет вызвано ReadCompletion, прочитанные данные будут записаны с использованием перекрывающегося WriteFileEx. 4. Будет вызван WriteCompletion, установите указатель на следующие 524288 байт и прочитайте 5. (и так далее) две подпрограммы завершения будут вызывать друг друга до тех пор, пока все данные не будут переданы

MyClass.h

struct MY_OVERLAPPED: OVERLAPPED {
    MyClass *event;
    unsigned long long count;
};

MyClass.cpp - main

MY_OVERLAPPED overlap;
memset(&overlap, 0,sizeof(overlap));

//point to this class (MyClass), so all variables can later be accessed
overlap.event = this; 

//set read position******how do I not use Offset??
overlap.Offset = 0;
overlap.OffsetHigh = 0;
overlap.count = 0;

//start the first read io request, read 524288 bytes, which 524288 bytes will be written in ReadCompletionRoutine
ReadFileEx(overlap.event->hSource, overlap.event->data, 524288, &overlap, ReadCompletionRoutine);

SleepEx(0,TRUE);

MyClass.cpp - ЗВОНОКИ

void CALLBACK ReadCompletionRoutine(DWORD errorCode, DWORD bytestransfered, LPOVERLAPPED lpOverlapped)
{
    //type cast to MY_OVERLAPPED
    MY_OVERLAPPED *overlap = static_cast<MY_OVERLAPPED*>(lpOverlapped);

    //write 524288 bytes and continue to read next 524288 bytes in WriteCompletionRoutine
    WriteFileEx(overlap->event->hDevice, overlap->event->data, 524288, overlap, WriteCompletionRoutine);
}

void CALLBACK WriteCompletionRoutine(DWORD errorCode, DWORD bytestransfered, LPOVERLAPPED lpOverlapped)
{
    MY_OVERLAPPED *overlap = static_cast<MY_OVERLAPPED*>(lpOverlapped);

    //set new offset to 524288*i, i = overlap->count for next block reading
    overlap->count = (overlap->count)+1;
    LARGE_INTEGER location;
    location.QuadPart = 524288*(overlap->count);
    overlap->Offset = location.LowPart;
    overlap->OffsetHigh = location.HighPart;

    ReadFileEx(overlap->event->hSource, overlap->event->data, 524288, overlap, ReadCompletionRoutine);
}
...