Асинхронный ввод/вывод
void Clab6Dlg::OutputData(void)
{
bool bASyncIO = ((CButton*)(GetDlgItem(IDC_RADIO_ASYNC)))->GetCheck() == BST_CHECKED;
OVERLAPPED over;
DWORD dwFlags = FILE_FLAG_RANDOM_ACCESS | FILE_ATTRIBUTE_NORMAL;
if (bASyncIO)
dwFlags |= FILE_FLAG_OVERLAPPED;
m_hFile = CreateFile("a:\\my_file.txt",
GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
CREATE_ALWAYS,
dwFlags,
0);
if (INVALID_HANDLE_VALUE == m_hFile)
{
AfxMessageBox("Ошибка создания файла",
MB_ICONEXCLAMATION,
0);
return;
}
HANDLE hEvent = CreateEvent(NULL,
TRUE,
TRUE,
NULL);
over.hEvent = hEvent;
over.OffsetHigh = 0;
over.Offset = 0;
// Настройка полосы состояния
m_prgsState.SetRange32(0, 400000);
m_prgsState.SetPos(0);
m_prgsState.SetStep(1);
unsigned long ulArray[ 10000 ];
unsigned long ulSimple = 2;
for (long lGlobalCount = 0; lGlobalCount < 40; lGlobalCount++)
{
// Ожидание конца записи в файл
if (bASyncIO)
WaitForSingleObject(over.hEvent, INFINITE);
// Подготовка очередной порции данных
for (long i = 0; i < 10000;)
{
if (IsNumSimple(ulSimple))
ulArray[ i++ ] = ulSimple;
ulSimple++;
m_prgsState.StepIt();
}
DWORD r;
WriteFile(m_hFile,
ulArray,
sizeof(ulArray),
&r,
bASyncIO == true ? &over : NULL);
over.Offset += sizeof(ulArray);
}
CloseHandle(hEvent);
CloseHandle(m_hFile);
AfxMessageBox("Операция завершена", 0, 0);
}
Нужно в программе продемонстрировать работу ввода/вывода такого типа. Все в роде бы сделал по науке, но правильно ли? Как я ни старался, WaitForSIngleObject выходит у меня без ожидания, хотя я ставил достаточно большие циклы, и пишу файл на дискетту, для замедления вывода. Действительно операции проходят асинхронно? Должен ли Event быть AutoReset? Еще, как видите, я после записи порции данных в файл увеличиваю поле смещения в over. Не будет ли это влиять на уже запущенную запись? ФАйл, который создает программа по размеру совпадает с ожидаемым. Все ли я правильно сделал?
И еще такой вопрос. Он не совсем по теме, но... Хочу я эту операцию, вынести в отдельный поток. Но ихвестно, что операции, совершаемые над элементами управления, должны происходить в контексте того потока, который обрабатывает сообщения от данного контрола. Как этого добиться средствами API? Или только посылкой сообщений в очередь?
Заранее спасибо за советы
Попробуйте еще установить FILE_FLAG_NO_BUFFERING - тогда возможно увидите, как поток будет притормаживать на функциях ожидания. Дело в том, что по умолчанию ввод/вывод буферизируется - WriteFile даже в ассинхронном режиме вернет управление не дожидаясь физического окончания записи. Кстати, MSDN рекомендует FILE_FLAG_NO_BUFFERING использовать совместно с FILE_FLAG_OVERLAPPED