Есть Thread, в котором реализована некоторая процедура, в которой используется API функция DeviceIoControl (Handle, FSCTL_MOVE_FILE, ...); Как прервать выполнение данной функции(DeviceIoControl)? Делаю следующее private lSync: OVERLAPPED; .... constructor TmyThread.Create; ... FillChar(lSync, SizeOf(TOverlapped), 0); lSync.hEvent := CreateEvent(nil, true, FALSE, #0); ..... unction UnNormilizeDrive(const ADrivePath: string): string; begin Result := '//./' + Copy(ADrivePath, 1, Pos('\', ADrivePath) — 1) end; DeviceHandle := CreateFile(PAnsiChar(UnNormilizeDrive(DriveName)), GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE, nil, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); ... MoveParams.FileHandle := CreateFile(PAnsiChar(AFile.FileName), ; FILE_READ_ATTRIBUTES, FILE_SHAR E_READ OR FILE_SHARE_WRITE OR FILE_SHARE_DELETE, nil, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); if (MoveParams.FileHandle = INVALID_HANDLE_VALUE) then MoveParams.FileHandle := CreateFile(PAnsiChar(AFile.FileName), GENERIC_READ, FILE_SHARE_READ OR FILE_SHARE_WRITE OR FILE_SHARE_DELETE, nil, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); .... AResult := DeviceIoControl(DeviceHandle, FSCTL_MOVE_FILE, @MoveParams, sizeof(MoveParams), nil, 0, w, @lSync); if (not AResult) then begin .... end; //По идее сюда должно быть передано управление сразу же. Однако управление не предается, а ждет окончания выполнения функции //DeviceIoControl.. Что сделано не так? Как добиться того, чтобы можно было прервать операцию... //Далее идет код, который и должен прервать операцию procedure TmyThread.StopProc; begin SetEvent(lSync.hEvent); end;
Event, на который указывает lSync предусмотрен не для прерывания, AFAIK. Система устанавливает его сигнальный статус по окончании выполнения команды. Т.е. этот event предусмотрен лишь для слежения за завершением операции. Чтоб прервать тред, можно использовать TerminateThread, но это чревато нехорошими последствиями. Лучше копировать файл поблочно и после каждого блока проверять состояние флага синхронизации.
>Лучше копировать файл поблочно и после каждого блока проверять состояние флага синхронизации. Это как?
salexn Допустим, размер файла x байт. Делим файл на n кусков по k байт. k для большей эффективности будет кратно размеру кластера. Делаем цикл (псевдокод): Код (Text): for(i = 0; i < n; i++){ copy(/* следующий блок */); if(flag == 1){ close_file(); clean_up(); // *** exit_thread(); } } Для остановки этого треда достаточно выставить флаг (flag = 1) и подождать немного.
>Quantum Даа... А вы гарантируете, что после такого действия файл не будет фрагментированным... Я нет.
salexn Причём тут фрагментация? Почитайте на досуге про файловые системы. Зато хладнокровно кильнуть тред, который копирует файл может, в лучшем случае, "засорить" ваш диск, а в худшем...