Форум: "WinAPI";
Текущий архив: 2006.08.20;
Скачать: [xml.tar.bz2];
ВнизКак остановить выполнение потока Найти похожие ветки
← →
sally (2006-04-26 17:49) [0]Есть Thread, в котором реализована некоторая процедура, в которой используется API функция
DeviceIoControl (Handle, FSCTL_MOVE_FILE, ...);
Если файл "большой", т.е. занимает много кластеров, то до тех пор пока он не будет перемещен никакой Terminate не помогает. Можно ли как то прервать выполнение данной функции(DeviceIoControl)?
← →
Игорь Шевченко © (2006-04-26 17:51) [1]
> Если файл "большой", т.е. занимает много кластеров, то до
> тех пор пока он не будет перемещен никакой Terminate не
> помогает
Смотреть в сторону параметра Overlapped в функции DeviceIoControl.
> Можно ли как то прервать выполнение данной функции(DeviceIoControl)?
CancelIO(Ex) ?
← →
sally (2006-04-27 12:43) [2]Спасибо. Попробовал, но чего то не получается
делаю так:
private
lSync: OVERLAPPED;
на создании потока
FillChar(lSync, SizeOf(TOverlapped), 0);
lSync.hEvent := CreateEvent(nil, true, FALSE, #0);
далее
MoveParams.FileHandle := CreateFile(PAnsiChar(AFile.FileName), FILE_READ_ATTRIBUTES, FILE_SHARE_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);
....
while WaitForSingleObject(MoveParams.FileHandle, 10) = 0 do
begin
AResult := DeviceIoControl(Volume.Handle, FSCTL_MOVE_FILE, @MoveParams,
sizeof(MoveParams), nil, 0, w, @lSync);
if Terminated then
begin
CancelIo(MoveParams.FileHandle);
Break;
end;
end;
То что выделено жирным, это так было(вместо @lSync был nil). Все работало, но нельзя было остановить. Где я чего не так сделал?
← →
Сергей М. © (2006-04-27 12:54) [3]try
AResult := DeviceIoControl(Volume.Handle, FSCTL_MOVE_FILE, @MoveParams,
sizeof(MoveParams), nil, 0, w, @lSync);
Win32Check(AResult);
try
while not Terminated do and (WaitForSingleObject(lSync.hEvent, 10) <> WAIT_OBJECT_0) do;
finally
CanselIO(MoveParams.FileHandle);
end;
except
..
end;
← →
Игорь Шевченко © (2006-04-27 12:57) [4]
> Где я чего не так сделал?
Как минимум, не проверил состояние операции. Кроме того, при асинхронной операции управление в программу возвращается сразу после вызова DeviceIoControl, после него нужен WaitForMultipleObjects, где один из объектов - это событие асинхронного ввода-вывода (Overlapped.hEvent), а другой - это событие на завершение потока, внешнее.
← →
Sally (2006-04-27 13:51) [5]>это событие на завершение потока
А это что?
← →
Polevi © (2006-04-27 13:57) [6]это некий объект при сигнале которого поточная ф-ия завершает свою работу
переводить этот объект в сигнальное состояние должен ты когда пожелаешь "остановить выполнение потока"
← →
Sally (2006-04-27 14:44) [7]а где про все это можно прочитать подробно желательно с примерами?
← →
Сергей М. © (2006-04-27 15:21) [8]
> Sally (27.04.06 14:44) [7]
msdn.microsoft.com
← →
Игорь Шевченко © (2006-04-27 15:37) [9]
> а где про все это можно прочитать подробно желательно с
> примерами?
Джеффри Рихтер, программирование для Win32
← →
sally (2006-04-27 18:50) [10]сделал следующее:
private
DeviceIoSync: OVERLAPPED;
ThreadSync: OVERLAPPED;
.....
public
procedure StopThread;
procedure TThread1.StopThread;
begin
SetEvent(ThreadSync.hEvent);
Self.Terminate;
end;
constructor ....
FillChar(DeviceIoSync, SizeOf(TOverlapped), 0);
FillChar(ThreadSync, SizeOf(TOverlapped), 0);
DeviceIoSync.hEvent := CreateEvent(nil, true, FALSE, #0);
ThreadSync.hEvent := CreateEvent(nil, true, FALSE, #0);
....
Handles[0] := DeviceIoSync.hEvent;
Handles[1] := ThreadSync.hEvent;
....
AResult := DeviceIoControl(Volume.Handle, FSCTL_MOVE_FILE, @MoveParams, sizeof(MoveParams), nil, 0, w, @DeviceIoSync);
Win32Check(AResult);
AReason := WaitForMultipleObjects(2, @Handles, False, INFINITE);
case AReason of
WAIT_OBJECT_0: Result := mfrSuccess;
WAIT_OBJECT_0 + 1, WAIT_ABANDONED_0 + 1, WAIT_ABANDONED_0: CancelIO(MoveParams.FileHandle);
end;;
Не выходит из DeviceIoControl....
← →
Игорь Шевченко © (2006-04-27 18:59) [11]
> Не выходит из DeviceIoControl....
???? Как не выходит
← →
Sally (2006-04-27 19:00) [12]Сорри...
Не выходит из
AReason := WaitForMultipleObjects(2, @Handles, False, INFINITE);
← →
Sally (2006-04-27 19:00) [13]В догонку.... В смысле не останавливает процесс перемещения файла.
← →
Игорь Шевченко © (2006-04-27 19:01) [14]http://www.sysinternals.com/Information/DiskDefragmenting.html
← →
Игорь Шевченко © (2006-04-27 19:02) [15]
> В догонку.... В смысле не останавливает процесс перемещения
> файла.
А как ты себе представляешь остановку процесса перемещения файла ? Половина кластеров переместилась, а половина на старом месте ?
← →
Sally (2006-04-27 19:06) [16]Ну это я не придумал, просто дефрагментаторы при остановке дефрагментации не ждут окончания переноса файла. Большие файлы соответственно долго переносятся. Так вот если остановить процесс во время дефрагментации этого файла он остается на месте и не дефрагментируется.
← →
Игорь Шевченко © (2006-04-27 19:10) [17]Sally (27.04.06 19:06) [16]
А по ссылке ничего не подходит ?
← →
Sally (2006-04-27 19:18) [18]Не, там ничего такого нет...
← →
Sally (2006-04-27 19:23) [19]А может быть дело в INFINITE?
← →
Sally (2006-04-27 19:39) [20]AResult := DeviceIoControl(Volume.Handle, FSCTL_MOVE_FILE, @MoveParams, sizeof(MoveParams), nil, 0, w, @DeviceIoSync);
Не выходит именно из этой операции!!!
← →
Сергей М. © (2006-04-28 08:54) [21]
> Не выходит именно из этой операции
Быть того не может.
Цитата из справки к DeviceIoControl:
If hDevice was opened with the FILE_FLAG_OVERLAPPED flag, this parameter must point to a valid OVERLAPPED structure. In this case, DeviceIoControl is performed as an overlapped (asynchronous) operation. If the device was opened with FILE_FLAG_OVERLAPPED and lpOverlapped is NULL, the function fails in unpredictable ways.
If hDevice was opened without specifying the FILE_FLAG_OVERLAPPED flag, this parameter is ignored and the DeviceIoControl function does not return until the operation has been completed, or an error occurs.
← →
sally (2006-04-28 10:17) [22]>Сергей М
Я тоже умею пользоваться Ctrl+C и Ctrl+V
>Быть того не может.
Это из цикла:
-Ты суслика видишь.
-Нет.
-И я нет, а он есть
Функция ожидает окончания процесса перемещения.
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);
Так "создается" девайс.
в [10] все далее.
← →
Сергей М. © (2006-04-28 10:41) [23]
> sally (28.04.06 10:17) [22]
А останов треда по Program Pause при этом нормально происходит ?
Я к тому что здесь всего два варианта : либо overlapped-режим не задействован, либо при вызове DeviceIoControl происходит исключение.
← →
Игорь Шевченко © (2006-04-28 11:02) [24]Какой результат возвращает DeviceIoControl после начала операции ?
← →
Sally (2006-04-28 11:02) [25]>А останов треда по Program Pause при этом нормально происходит
Это что такое?
В смысле, если Thread.Terminate или Thread.Suspend сдедать?
Нормально... Т.е. DeviceIoControl продолжает выполнение операции :) Вот когда он закончит, тогда Thread и дестроится.
Почему-то не включается overlapped режим...
← →
Сергей М. © (2006-04-28 11:13) [26]
> Это что такое?
Это меню Run -> Program Pause
← →
Игорь Шевченко © (2006-04-28 11:13) [27]При начале асинхронной операции функция GetLastError должна возращать ERROR_IO_PENDING (997)
← →
Sally (2006-04-28 11:24) [28]>Какой результат возвращает DeviceIoControl после начала операции
DeviceIoControl ждет окончания операции. Он ничего не возвращает.
Повотрюсь, скорее всего не включается overlapped режим...
← →
Сергей М. © (2006-04-28 11:47) [29]Попробуй использовать NtFsControlFile вместо DeviceIoControl.
Кстати, ты ОС не обозначил, скорей всего есть какие-то системозависимые ограничения в этой части.
← →
sally (2006-04-28 12:05) [30]Прикольно, но ни в MSDN ни на сайте msdn.microsoft.com ничего про эту функцию нет...
Попробуем...
← →
sally (2006-04-28 15:22) [31]Дааа... А может кто видел реализацию NTDDK.H для Delphi
← →
Игорь Шевченко © (2006-04-28 15:26) [32]
> ... А может кто видел реализацию NTDDK.H для Delphi
на www.delphi-jedi.org поищи
еще здесь кое-что: http://kladovka.net.ru/download.cgi?id=48
← →
Sally (2006-04-28 15:29) [33]То что нужно. Спасибо
← →
Sally (2006-04-28 16:09) [34]Скажите, этот высов правильный, для того, чтобы установить OVERLAPPED режим?
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);
function UnNormilizeDrive(const ADrivePath: string): string;
begin
Result := "//./" + Copy(ADrivePath, 1, Pos("\", ADrivePath) - 1)
end;
Потому что и с NtFsControlFile ничего не получается.
← →
Игорь Шевченко © (2006-04-28 16:13) [35]Sally (28.04.06 16:09) [34]
Я бы, как минимум, добавил GENERIC_WRITE, так как операции по перемещению файла по идее требуют доступ на запись.
Я бы, как минимум, вставил бы просто имя диска, соответственно требованиям CreateFile, для исключения остальных проблем на данном этапе.
И вообще, постарался бы написать простой пример, который можно вопроизвести другими.
← →
Сергей М. © (2006-04-28 16:18) [36]Если DeviceHandle = True, то вызов правильный.
Но я бы добавил к FILE_FLAG_OVERLAPPED флаг FILE_FLAG_NO_BUFFERING.
← →
Sally (2006-04-28 16:26) [37]Ничего тогда не понимаю...
status := NtFsControlFile(Volume.Handle, DeviceIoSync.hEvent, nil, nil, @ioStatus, FSCTL_MOVE_FILE, @MoveParams, sizeof(MoveParams), nil, 0);
if ( status = STATUS_PENDING ) then
begin
WaitForSingleObject(MoveParams.FileHandle, INFINITE);
status := ioStatus.Status;
end;
Ниразу он внутрь if не заходит.
← →
Игорь Шевченко © (2006-04-28 16:44) [38]Sally (28.04.06 16:26) [37]
А чему равен Status ?
← →
Sally (2006-04-28 16:49) [39]Status=0
← →
Сергей М. © (2006-04-28 16:54) [40]http://www.sysinternals.com/Information/DiskDefragmenting.html
Это читал ?
← →
Игорь Шевченко © (2006-04-28 17:01) [41]
> Status=0
На файле любого размера ?
← →
Sally (2006-04-28 17:04) [42]>Сергей М.
Читал
>Игорь Шевченко
Да
Страницы: 1 2 вся ветка
Форум: "WinAPI";
Текущий архив: 2006.08.20;
Скачать: [xml.tar.bz2];
Память: 0.55 MB
Время: 0.038 c