Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Асинхронное чтение файла, Не читает, проскакивает, как синхронный 
:(
    Опции темы
idti
Дата 10.4.2010, 21:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 139
Регистрация: 28.2.2009
Где: pnz

Репутация: нет
Всего: нет




Вот код из документации, работает, но синхронно=(
http://msdn.microsoft.com/en-us/library/aa365690(VS.85).aspx
Вот тут возможные способы решения:
http://support.microsoft.com/kb/156932
У кого-нибудь работает этот код асинхронно?

Код

#include <windows.h>
#include <tchar.h>
#include <stdio.h>

#define BUF_SIZE (512)

LPCTSTR ErrorMessage( DWORD error ) 

// Routine Description:
//      Retrieve the system error message for the last-error code
{ 

    LPVOID lpMsgBuf;

    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        error,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR) &lpMsgBuf,
        0, NULL );

    return((LPCTSTR)lpMsgBuf);
}

void GoDoSomethingElse(void)

// Routine Description:
//     Placeholder to demo when async I/O might want to do
//     other processing.
{
    printf("Inside GoDoSomethingElse()\n");
}

DWORD AsyncTestForEnd( HANDLE hEvent, HANDLE hFile )

// Routine Description:
//      Demonstrate async ReadFile operations that can catch
//      End-of-file conditions. Unless the operation completes
//      synchronously or the file size happens to be an exact
//      multiple of BUF_SIZE, this routine will eventually force
//      an EOF condition on any file.

// Parameters:
//      hEvent - pre-made manual-reset event.
//
//      hFile - pre-opened file handle, overlapped.
//
//      inBuffer - the buffer to read in the data to.
//
//      nBytesToRead - how much to read (usually the buffer size).

// Return Value:
//      Number of bytes read.
{
    
    char inBuffer[BUF_SIZE];
    DWORD nBytesToRead      = BUF_SIZE;
    DWORD dwBytesRead       = 0;
    DWORD dwFileSize        = GetFileSize(hFile, NULL);
    OVERLAPPED stOverlapped = {0};

    DWORD dwError  = 0;
    LPCTSTR errMsg = NULL;

    BOOL bResult   = FALSE;
    BOOL bContinue = TRUE;

    // Set up overlapped structure event. Other members are already 
    // initialized to zero.
    stOverlapped.hEvent = hEvent; 

    // This is an intentionally brute-force loop to force the EOF trigger.
    // A properly designed loop for this simple file read would use the
    // GetFileSize API to regulate execution. However, the purpose here
    // is to demonstrate how to trigger the EOF error and handle it.

    while(bContinue)
    {
        // Default to ending the loop.
        bContinue = FALSE;
        
        // Attempt an asynchronous read operation.
        bResult = ReadFile(hFile,
                           inBuffer,
                           nBytesToRead,
                           &dwBytesRead,
                           &stOverlapped); 
     
        dwError = GetLastError();

        // Check for a problem or pending operation. 
        if (!bResult) 
        { 
            switch (dwError) 
            { 
                 
                case ERROR_HANDLE_EOF:
                {
                    printf("\nReadFile returned FALSE and EOF condition, async EOF not triggered.\n");
                    break;
                }
                case ERROR_IO_PENDING: 
                { 
                    BOOL bPending=TRUE;

                    // Loop until the I/O is complete, that is: the overlapped 
                    // event is signaled.

                    while( bPending )
                    {
                        bPending = FALSE;
                        
                        // Pending asynchronous I/O, do something else
                        // and re-check overlapped structure.
                        printf("\nReadFile operation is pending\n");
     
                        // Do something else then come back to check. 
                        GoDoSomethingElse(); 
     
                        // Check the result of the asynchronous read
                        // without waiting (forth parameter FALSE). 
                        bResult = GetOverlappedResult(hFile,
                                                      &stOverlapped,
                                                      &dwBytesRead,
                                                      FALSE) ; 
     
                        if (!bResult) 
                        { 
                            switch (dwError = GetLastError()) 
                            { 
                                case ERROR_HANDLE_EOF: 
                                { 
                                    // Handle an end of file
                                    printf("GetOverlappedResult found EOF\n");
                                    break;
                                } 

                                case ERROR_IO_INCOMPLETE:
                                {
                                    // Operation is still pending, allow while loop
                                    // to loop again after printing a little progress.
                                    printf("GetOverlappedResult I/O Incomplete\n");
                                    bPending = TRUE;
                                    bContinue = TRUE;
                                    break;
                                }

                                default:
                                {
                                    // Decode any other errors codes.
                                    errMsg = ErrorMessage(dwError);
                                    _tprintf(TEXT("GetOverlappedResult failed (%d): %s\n"), 
                                        dwError, errMsg);
                                    LocalFree((LPVOID)errMsg);
                                }
                            }
                        } 
                        else
                        {
                            printf("ReadFile operation completed\n");

                            // Manual-reset event should be reset since it is now signaled.
                            ResetEvent(stOverlapped.hEvent);
                        }
                    }
                    break;
                }

                default:
                {
                    // Decode any other errors codes.
                    errMsg = ErrorMessage(dwError);
                    printf("ReadFile GLE unhandled (%d): %s\n", dwError, errMsg); 
                    LocalFree((LPVOID)errMsg);
                    break;
                }
            }
        }
        else
        {
            // EOF demo did not trigger for the given file.
            // Note that system caching may cause this condition on most files
            // after the first read. CreateFile can be called using the
            // FILE_FLAG_NOBUFFERING parameter but it would require reads are
            // always aligned to the volume's sector boundary. This is beyond
            // the scope of this example. See comments in the main() function.

            printf("ReadFile completed synchronously\n");
        }

        // The following operation assumes the file is not extremely large, otherwise 
        // logic would need to be included to adequately account for very large
        // files and manipulate the OffsetHigh member of the OVERLAPPED structure.

        stOverlapped.Offset += dwBytesRead;
        if ( stOverlapped.Offset < dwFileSize )             
            bContinue = TRUE;
    }

    return stOverlapped.Offset;
}

void __cdecl _tmain(int argc, TCHAR *argv[])

// To force an EOF condition, execute this application specifying a
// zero-length file. This is because the offset (file pointer) must be
// at or beyond the end-of-file marker when ReadFile is called. For
// more information, see the comments for the AsyncTestForEnd routine.

{
    HANDLE hEvent;
    HANDLE hFile;
    DWORD dwReturnValue;

    printf("\n");
    if( argc != 1 )//2 )
    {
        printf("ERROR:\tIncorrect number of arguments\n\n");
        printf("%s <file_name>\n", argv[0]);
        return;
    }

    hFile = CreateFile(TEXT("c:\\one.txt"),//argv[1],                // file to open
                       GENERIC_READ,           // open for reading
                       FILE_SHARE_READ,        // share for reading
                       NULL,                   // default security
                       OPEN_EXISTING,          // existing file only
                       FILE_FLAG_OVERLAPPED & FILE_FLAG_NO_BUFFERING,   // overlapped operation
                       NULL);                  // no attr. template
 
    if (hFile == INVALID_HANDLE_VALUE) 
    { 
        DWORD dwError = GetLastError();
        LPCTSTR errMsg = ErrorMessage(dwError);
        printf("Could not open file (%d): %s\n", dwError, errMsg); 
        LocalFree((LPVOID)errMsg);
        return; 
    }

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

    if (hEvent == NULL) 
    { 
        DWORD dwError = GetLastError();
        LPCTSTR errMsg = ErrorMessage(dwError);
        printf("Could not CreateEvent: %d %s\n", dwError, errMsg); 
        LocalFree((LPVOID)errMsg);
        return; 
    }

    dwReturnValue = AsyncTestForEnd(hEvent, hFile);

    printf( "\nRead complete. Bytes read: %d\n", dwReturnValue);

    CloseHandle(hFile);
    CloseHandle(hEvent);
}


PM MAIL   Вверх
Alexeis
Дата 10.4.2010, 22:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 7
Всего: 459



Цитата(idti @  10.4.2010,  20:39 Найти цитируемый пост)
У кого-нибудь работает этот код асинхронно?

  Так он работает асинхронно, просто дожидается конца операции. В тестовом примере нет других задач на которые можно было бы переключиться. 
  Можно по таймеру вызывать bResult = GetOverlappedResult( и проверять окончание операции. Тут же проверка идет в бесконечном цикле, фактически синхронная операция делается через асинхронную.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
idti
Дата 11.4.2010, 10:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 139
Регистрация: 28.2.2009
Где: pnz

Репутация: нет
Всего: нет



Цитата(Alexeis @  10.4.2010,  22:21 Найти цитируемый пост)
Так он работает асинхронно, просто дожидается конца операции. 

Если бы он работал асинхронно выводились бы соответствующие сообщения. А выводятся сообщения соответствующие синхронному сценарию.
Цитата(Alexeis @  10.4.2010,  22:21 Найти цитируемый пост)
В тестовом примере нет других задач на которые можно было бы переключиться. 

А как же:
Код

// Do something else then come back to check. 
GoDoSomethingElse(); 

Код сюда вообще не переходит.

Цитата(Alexeis @  10.4.2010,  22:21 Найти цитируемый пост)
Тут же проверка идет в бесконечном цикле, фактически синхронная операция делается через асинхронную.

Если имеется ввиду проверка GetOverlappedResult, то в этом и проблема, код выполняется вот по этому сценарию:

Код

        else
        {
            // EOF demo did not trigger for the given file.
            // Note that system caching may cause this condition on most files
            // after the first read. CreateFile can be called using the
            // FILE_FLAG_NOBUFFERING parameter but it would require reads are
            // always aligned to the volume's sector boundary. This is beyond
            // the scope of this example. See comments in the main() function.

            printf("ReadFile completed synchronously\n");
        }

Т. е.  ReadFile не возвращает управление. ReadFile не возвращает ошибку с флагом Ожидание_ВводаВывода. Вместо этого он сразу возвращает результат. И в коментарии этой ветки кода написано, что такое состояние может быть вызвано кешированием после первого чтения, но и при первом чтении не работает.


PM MAIL   Вверх
xvr
Дата 12.4.2010, 11:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



А что именно вы пытались асинхронно читать? Если это обычный файл, то для него это может и не работать. Нужно почитать что нибудь из каких нибудь коммуникационных каналов, для них должно работать


PM MAIL   Вверх
idti
Дата 12.4.2010, 15:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 139
Регистрация: 28.2.2009
Где: pnz

Репутация: нет
Всего: нет



Цитата(xvr @  12.4.2010,  11:57 Найти цитируемый пост)
Если это обычный файл, то для него это может и не работать.

Почему нет? Обычный текстовый файл 200мб.

Добавлено через 2 минуты и 9 секунд
Цитата(xvr @  12.4.2010,  11:57 Найти цитируемый пост)
Нужно почитать что нибудь из каких нибудь коммуникационных каналов

Например?
PM MAIL   Вверх
xvr
Дата 12.4.2010, 16:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



Цитата(idti @ 12.4.2010,  15:37)
Цитата(xvr @  12.4.2010,  11:57 Найти цитируемый пост)
Если это обычный файл, то для него это может и не работать.

Почему нет? Обычный текстовый файл 200мб.

Читать тут (с главы Asynchronous I/O Still Appears to be Synchronous)

Цитата

Добавлено @ 15:39
Цитата(xvr @  12.4.2010,  11:57 Найти цитируемый пост)
Нужно почитать что нибудь из каких нибудь коммуникационных каналов

Например?
Например из COM порта. Или на худой конец из Pipe'а

PM MAIL   Вверх
idti
Дата 12.4.2010, 22:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 139
Регистрация: 28.2.2009
Где: pnz

Репутация: нет
Всего: нет



Цитата(xvr @  12.4.2010,  16:19 Найти цитируемый пост)
Читать тут (с главы Asynchronous I/O Still Appears to be Synchronous)

Спасибо, это ссылка из моего первого поста, я там читал все. Там не написано про коммуникационный каналы, с чего Вы взяли? 
Цитата(xvr @  12.4.2010,  16:19 Найти цитируемый пост)
Например из COM порта. Или на худой конец из Pipe'а

Com порта нет=(, да и писать в него нечего. А pipe это что? Это разве не любой коммуникационный канал | - типа труба.

PM MAIL   Вверх
xvr
Дата 12.4.2010, 22:33 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



Цитата(idti @ 12.4.2010,  22:16)
Цитата(xvr @  12.4.2010,  16:19 Найти цитируемый пост)
Читать тут (с главы Asynchronous I/O Still Appears to be Synchronous)

Спасибо, это ссылка из моего первого поста, я там читал все. 

Ну и?

Цитата

Там не написано про коммуникационный каналы, с чего Вы взяли? 
Там написанно, что при чтении из файла асинхронного ввода вывода может и не случится. При обращении с коммуникационным каналом он случится точно (хотя там этого и не написанно  smile )

Цитата

Цитата(xvr @  12.4.2010,  16:19 Найти цитируемый пост)
Например из COM порта. Или на худой конец из Pipe'а

Com порта нет=(, да и писать в него нечего. А pipe это что? Это разве не любой коммуникационный канал | - типа труба.
CreatePipe, CreateNamedPipe

PS. В оригинальном исходнике в строке 231 ошибка: FILE_FLAG_OVERLAPPED & FILE_FLAG_NO_BUFFERING а должно быть FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING


Это сообщение отредактировал(а) xvr - 12.4.2010, 22:36
PM MAIL   Вверх
idti
Дата 13.4.2010, 21:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 139
Регистрация: 28.2.2009
Где: pnz

Репутация: нет
Всего: нет



Цитата(xvr @  12.4.2010,  22:33 Найти цитируемый пост)
CreatePipe, CreateNamedPipe

Так это что, типа виртуальный канал? Поищу.
Цитата(xvr @  12.4.2010,  22:33 Найти цитируемый пост)
Ну и?

Неа, все проблемы которые там описаны у меня отсутствуют.
Цитата(xvr @  12.4.2010,  22:33 Найти цитируемый пост)
PS. В оригинальном исходнике в строке 231 ошибка: FILE_FLAG_OVERLAPPED & FILE_FLAG_NO_BUFFERING а должно быть FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING

Точно. Я знаю, это, к сожалению, ничего не меняет.

Добавлено через 9 минут и 27 секунд
Цитата(idti @  13.4.2010,  21:54 Найти цитируемый пост)
Точно. Я знаю, это, к сожалению, ничего не меняет.

А нет меняет=)
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.1939 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.