Почему WriteFileEx работает синхронно?
От: Аноним  
Дата: 31.01.08 16:43
Оценка:
Всем привет!
В MSDN написано, что WriteFileEx работает только в асинхронном режиме, у меня же она работает почему-то в синхронном. Накатал примерчик:

void ShowMsg(char* Msg){
    MessageBoxA(NULL, Msg, NULL, NULL);
};

void ShowMsg(char* Format, long Param1){
    char* Msg = new char[strlen(Format) + 1000];
    sprintf(Msg, Format, Param1);
    ShowMsg(Msg);
    delete[] Msg;
};

VOID CALLBACK FileIOCompletionRoutine(
                   DWORD dwErrorCode,
                   DWORD dwNumberOfBytesTransfered,
                   LPOVERLAPPED lpOverlapped
                   ){
                       ShowMsg("IO completed with error code %d", dwErrorCode);

}

void Test_WriteFileEx(char* FileName){
    HANDLE HFile = CreateFileA(FileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_FLAG_OVERLAPPED, NULL);
    if(HFile == INVALID_HANDLE_VALUE) {
        ShowMsg("Cannot open file. CreateFile: %d", GetLastError());
    }
    else{
        char* Buffer = new char[500000];
        OVERLAPPED Overlapped;
        ZeroMemory(&Overlapped, sizeof(Overlapped));
        Overlapped.Offset = GetFileSize(HFile, &Overlapped.OffsetHigh);
        if(Overlapped.Offset == INVALID_FILE_SIZE && GetLastError() != 0){
            ShowMsg("GetFileSize: %d", GetLastError());
        }
        else{
            if(WriteFileEx(HFile, Buffer, 500000, &Overlapped, &FileIOCompletionRoutine) == 0){
                ShowMsg("WriteFileEx: %d", GetLastError());
            }
            else{
                DWORD Res = SleepEx(15000, TRUE);
                ShowMsg("WriteFileEx: success");
                switch(Res){
                    case 0:
                        ShowMsg("SleepEx: Timeout");
                    break;
                    case WAIT_IO_COMPLETION:
                        ShowMsg("SleepEx: IO completion");
                    break;
                    default:
                        ASSERT(false);
                }
            };
        };
        CloseHandle(Overlapped.hEvent);
        CloseHandle(HFile);
        delete[] Buffer;
    };
 
}


Передаю в качестве FileName файл на дискетке. Сначала всё очень долго пыхтит, а затем последовательно появляются сообщения:
IO completed with error code 0

WriteFileEx: success

SleepEx: IO completion

что означает, что FileIOCompletionRoutine вызывается внутри WriteFileEx
Re: Почему WriteFileEx работает синхронно?
От: Sergey Chadov Россия  
Дата: 31.01.08 17:54
Оценка: 1 (1)
Здравствуйте, <Аноним>, Вы писали:

А>Всем привет!

А>В MSDN написано, что WriteFileEx работает только в асинхронном режиме, у меня же она работает почему-то в синхронном. Накатал примерчик:

WriteFileEx _может_ работать асинхронно. Но может не всегда.
Например, здесь написано:

One nuance of Windows' asynchronous I/O facility is that, depending on the API you use, you may or may not actually get an async operation back from the OS. IOW, although you request an operation to be carried out asynchronously, Windows may decide to run it synchronously and may hold up your API call until the operation completes. The OS always makes the final decision on whether an async I/O request is honored. What happens when Windows decides not to honor an async I/O request depends on the API. For ReadFile/WriteFile, they simply block until the operation completes and return TRUE. You have to check their return values and respond accordingly -- you can't write code that expects the operation to complete at some point in the future if the operation actually finished immediately. For ReadFileEx/WriteFileEx, the API returns TRUE regardless of whether the action is carried out synchronously or asynchronously. I'm not aware of an easy way to detect that an async I/O request has been carried out synchronously using ReadFileEx or WriteFileEx.



Мои экспериметны показывают, что поведение WriteFileEx сильно зависит не только от данных, но и от модели чипсета и версии дров и еще хрен знает чего.

Сам код не смотрел, может ошибка там, но вышенаписанное нужно иметь ввиду.
--
Sergey Chadov

... << RSDN@Home 1.2.0 alpha rev. 685>>
Re: Почему WriteFileEx работает синхронно?
От: Vacabi  
Дата: 31.01.08 18:22
Оценка: 1 (1)
Здравствуйте, Аноним, Вы писали:

А>В MSDN написано, что WriteFileEx работает только в асинхронном режиме, у меня же она работает почему-то в синхронном.


Чтобы файловые операции действительно выполнялись асинхронно, нужно выполнить кучу условий: http://support.microsoft.com/kb/156932
Мои ¢2
-- Vacabi
Re[2]: Почему WriteFileEx работает синхронно?
От: AdUser  
Дата: 01.02.08 08:10
Оценка:
Здравствуйте, Vacabi, Вы писали:

V>Чтобы файловые операции действительно выполнялись асинхронно, нужно выполнить кучу условий: http://support.microsoft.com/kb/156932


Спасибо за ответ. Ошибок в использовнии ф-ции я у себя не нашёл. Главное, что вытекает из статьи: никто ни в каком случае не гарантирует асинхронность работы ф-ций WriteFile/WriteFileEx. Я ещё поигрался с этими ф-циями. На 32-битной Висте у меня WriteFile всегда работает асинхронно (даже если я пишу всего 200 байт на жёсткий диск), заставить работать асинхронно WriteFileEx мне так и не удалось. На XP и WriteFileEx, и WriteFile у меня работали только синхронно. Вот такое странное поведение
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.