Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "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
1-1152013774
Искандер В.
2006-07-04 15:49
2006.08.20
Нестандартные шрифты


2-1154019946
zhekacoder
2006-07-27 21:05
2006.08.20
Что такое pointer


2-1154347864
Dysan
2006-07-31 16:11
2006.08.20
русские буквы в XML файле вызывают ошибку!


2-1154344342
Дева
2006-07-31 15:12
2006.08.20
как умнее


1-1152077296
dreamse
2006-07-05 09:28
2006.08.20
Как вытащить дату из строки типа 03.07.06_17.-32-.21.txt





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский