Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 09.04.2009, 22:06   #1
Deathwatcher
Пользователь
 
Регистрация: 12.11.2008
Сообщений: 11
По умолчанию Проблемы с потоками...

Чего-то я засиделся и совсем ничего не понимаю. Нужна свежая мысль.
Исходные данные: монитор для слежения за папкой. В случае изменений каких-нибудь, писать в БД.

Проблема первая:
Просматриваю папку. Происходят изменения. Но в базу заносится произвольное количество записей, а не одна!
Вот так просматриваю
Код:
 repeat
   if ReadDirectoryChangesW(hDir, Buf, BufSize, SubDirs,
      FILE_NOTIFY_CHANGE_FILE_NAME or
      FILE_NOTIFY_CHANGE_LAST_WRITE or
      FILE_NOTIFY_CHANGE_LAST_ACCESS or
      FILE_NOTIFY_CHANGE_CREATION, @Returned, nil, nil) then
   begin
     Adr := Cardinal(Buf);
     while Adr < (Cardinal(Buf) + Returned) do
     begin
       case fni^.Action of
         FILE_ACTION_ADDED            : logtext := 'Added';
         FILE_ACTION_MODIFIED         : logtext := 'Modified';
         FILE_ACTION_REMOVED          : logtext := 'Removed';
         else logtext := '0x' + IntToHex(fni^.Action, 8);
       end;
        Synchronize(UpdateLog);
        exit;
     end;
   end;
 until False;
Вот так изменения вношу
Код:
procedure TMonitorThread.UpdateLog;     //обновление лога
begin
form3.ClientDataSet1.Append;
form3.ClientDataSet1['Название']:= 'файл '+logtext ;
form3.ClientDataSet1['Изменено']:= now  ;
end;
Проблема вторая(смешнее первой) не удается остановить поток!
так я его запускаю
Код:
form1.Tag:=Integer(TMonitorThread.Create('D:\Testmonitor'));
так пытаюсь остановить
Код:
if Assigned(TMonitorThread(Form1.Tag)) then
TMonitorThread(Form1.Tag).Terminate;    
Form1.Tag := 0;
Буду рад любой помощи!
Deathwatcher вне форума Ответить с цитированием
Старый 09.04.2009, 22:18   #2
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

не Терминаль поток а Suspend ему делай
я сам с этим мучался уже
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 10.04.2009, 00:54   #3
Антон Ю.Б.
Форумчанин
 
Регистрация: 03.01.2009
Сообщений: 116
По умолчанию

Делать Suspend всяко мало, а связка Suspend - Free не всегда корректно отрабатывает при занятии потоком ресурсов (особенно, если это связано с устройствами). Поэтому хочется посоветовать проверить установку в конструкторе потока в True свойства FreeOnTerminate, а извне проверять не assigned, а Tag=0 (в некоторых случаях более корректна логика создания нового потока, когда старый логически уже отработал, но физически мог еще освободить не все ресурсы и не уничтожиться).
Антон Ю.Б. вне форума Ответить с цитированием
Старый 10.04.2009, 08:31   #4
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию

Ошибка, в первом куске кода. Делать только так:
Код:
while not Terminated do.....
вместо
Код:
repeat...until false;
А то у вас вечный цикл.

Чтобы завершить поток в главном потоке, синхронно делаем так:

Код:
TThread.Terminate;
TThread.WaitFor;
TThread.Free;
На счет последнего поста. Вы не правы. Если поток (верней указатель на класс) хранится в переменной, то допустим поток освободится автоматически (FreeOnTerminate := True) то в переменной будет хранится значение, и Assigned вернет True.. дальше вы увидите при попытке использования этого потока всем известный Access valiation.....
BOBAH13 вне форума Ответить с цитированием
Старый 10.04.2009, 10:15   #5
Антон Ю.Б.
Форумчанин
 
Регистрация: 03.01.2009
Сообщений: 116
По умолчанию

BOBAH13, так совет совсем в ином состоял (не все правда ясно прописал). Он был в том, чтобы Form1.Tag := 0; делать в деструкторе потока одним из первых действий, а извне просто проверять Form1.Tag на не/равенство нулю, а не конструкцию типа Assigned. Дело даже не в использовании Assigned, а в порядке зануления (установки в Nil) переменной и уничтожения потока для некоторых ситуаций.
Антон Ю.Б. вне форума Ответить с цитированием
Старый 20.04.2009, 12:45   #6
Deathwatcher
Пользователь
 
Регистрация: 12.11.2008
Сообщений: 11
По умолчанию

в конструкторе FreeOnTerminate := True; проставляю (((

Цитата:
Сообщение от BOBAH13 Посмотреть сообщение

Чтобы завершить поток в главном потоке, синхронно делаем так:

Код:
TThread.Terminate;
TThread.WaitFor;
TThread.Free;
чего-то у меня вообще вся форма отмирает, а не только этот поток (((


Почему же все таки в БД заносится несколько событий??? очень не хочется предпроверки ставить при добавлении в БД??

Последний раз редактировалось Deathwatcher; 20.04.2009 в 13:05.
Deathwatcher вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Есть проблема с потоками DeeNamid Общие вопросы Delphi 2 01.11.2008 14:05
Проблема с потоками DeeNamid Общие вопросы Delphi 2 04.08.2008 17:36
работа с потоками Alex_Pro Общие вопросы .NET 1 01.07.2008 07:25
C++, работа с потоками mat90x Помощь студентам 20 15.05.2008 22:20
Проблема с потоками vitalik007 Общие вопросы Delphi 1 11.03.2008 22:35