Форум программистов, компьютерный форум, киберфорум
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/4: Рейтинг темы: голосов - 4, средняя оценка - 5.00
1 / 1 / 0
Регистрация: 22.10.2016
Сообщений: 105
1

Ошибка в потоке

16.10.2017, 23:36. Показов 827. Ответов 7
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Задача такая - я хочу в потоке отслеживать какие в данный момент на компьютере запущены приложения. В дальнейшем хочу реализовать функцию по контролю за работой персонала (т.е. запустил работник на компьютере танки и программа посылает мне сообщение об этом по эл.почте). Столкнулся с такой проблемой - программа то работает то ни работает. Сам понимаю что напортачил где-то с синхронизацией с визуальными компонентами, но ни могу понять где ошибка. Вроде по учебнику все сделал. Программа должна в мемо выводить все работающие приложения.

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
TMyThread=class(TThread)
  private
  {Private}
  protected
  procedure Execute;override;
  procedure ListboxAdd;
  end;
 
 
 
 
/Процедура потока для поиска открытых приложений
procedure TMyThread.ListboxAdd;
var
Wnd: hWnd;
buff: array [0..127] of Char;
begin
Form1.Memo1.Clear;
Wnd := GetWindow(Handle, gw_HWndFirst);
  while Wnd <> 0 do
  begin {Не показываем:}
    if (Wnd <> Application.Handle) and {Собственное окно}
      IsWindowVisible(Wnd) and  {Невидимые окна}
      (GetWindow(Wnd, gw_Owner) = 0) and  {Дочерние окна}
      (GetWindowText(Wnd, buff, sizeof(buff)) <> 0) then  //Окна без заголовков
      begin
      GetWindowText(Wnd, buff, sizeof(buff));
      Form1.Memo1.Lines.Insert(0,StrPas(buff));
      end;
    Wnd := GetWindow(Wnd, gw_hWndNext);
  end;
end;
 
//Поток
Procedure TMyThread.Execute;
begin
while True do
 begin
 Synchronize(ListboxAdd);
 sleep(100);
 end;
end;
 
//Запуск потока из тела программы
begin
ThreadKeeper:=TMyThread.Create(True);// Создаем поток
 ThreadKeeper.FreeOnTerminate:=true; // После завершения выполнения поток авто уничтожиться
 ThreadKeeper.Priority:=tpLower; //приоритет потока нормальный
 ThreadKeeper.Resume; //Запуск потока
end;
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
16.10.2017, 23:36
Ответы с готовыми решениями:

Ошибка в потоке
procedure TMyThread.Execute; begin response:=send('GET',...

Ошибка в потоке
http://картинки и другие файлы выкладывайте на форум Раньше не встречал такой ошибки, с чем...

Ошибка в потоке
Недопустимая операция в нескольких потоках: попытка доступа к элементу управления &quot;Tall&quot; не из того...

Ошибка в потоке
После авторизации я открываю окно &quot;ЗАГРУЗКА...&quot;, параллельно я открыл ещё одно скрытое окно куда...

7
Native x86
Эксперт Hardware
5513 / 3272 / 934
Регистрация: 13.02.2013
Сообщений: 10,421
17.10.2017, 00:16 2
В вашем случае функция с полезным кодом вызывается синхронно в контексте основного потока, нет никакого смысла в TThred. Если вы используете обычный TTimer, работать будет так же, но без потоковых проблем.

А еще вы зачем-то дважды вызываете GetWindowText.
0
1 / 1 / 0
Регистрация: 22.10.2016
Сообщений: 105
17.10.2017, 00:54  [ТС] 3
В основном потоке у меня другие операции выполняются. Хотелось бы эту операцию в др. поток вынести. Насчет GetWindowText согласен

Добавлено через 1 минуту
Если не получится сделать через TThred реализуюсь через Ttimer, но просто еще параллельно хотел получить знания по потокам
0
пофигист широкого профиля
4732 / 3167 / 858
Регистрация: 15.07.2013
Сообщений: 18,251
17.10.2017, 02:37 4
Цитата Сообщение от Vadim00311 Посмотреть сообщение
В основном потоке у меня другие операции выполняются.
А также и ListboxAdd. Ибо она вызывается из Synchronize.
Цитата Сообщение от Vadim00311 Посмотреть сообщение
просто еще параллельно хотел получить знания по потокам
Ну вот ещё одно знание вы считаем уже получили. Всё что выполняется в методе TThread.Synchronize выполняется в основном потоке.
0
1 / 1 / 0
Регистрация: 22.10.2016
Сообщений: 105
17.10.2017, 03:17  [ТС] 5
Получается я не правильно использую Synchronize ?
0
5784 / 4526 / 1431
Регистрация: 14.04.2014
Сообщений: 20,157
Записей в блоге: 20
17.10.2017, 09:06 6
помещайте в Synchronize ТОЛЬКО то что никак нельзя делать в потоке...
и цикл
While not Terminated do
...
тогда можно остановить поток
th.Terminate
0
1 / 1 / 0
Регистрация: 22.10.2016
Сообщений: 105
17.10.2017, 13:03  [ТС] 7
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//Процедура потока для поиска открытых приложений
procedure TMyThread.ListboxAdd;
begin
 Form1.Memo1.Clear;
Form1.Memo1.Lines.Insert(0,StrPas(buff));
end;
 
//Поток
Procedure TMyThread.Execute;
begin
while True do
 begin
 Wnd := GetWindow(Handle, gw_HWndFirst);
  while Wnd <> 0 do
  begin {Не показываем:}
    if (Wnd <> Application.Handle) and {Собственное окно}
      IsWindowVisible(Wnd) and  {Невидимые окна}
      (GetWindow(Wnd, gw_Owner) = 0) and  {Дочерние окна}
      (GetWindowText(Wnd, buff, sizeof(buff)) <> 0) then  //Окна без заголовков
       Synchronize(ListBoxAdd);
  end;
 Wnd := GetWindow(Wnd, gw_hWndNext);
 end;
 
end;
Сделал вот так и все равно не работает
0
Native x86
Эксперт Hardware
5513 / 3272 / 934
Регистрация: 13.02.2013
Сообщений: 10,421
17.10.2017, 16:22 8
Цитата Сообщение от Vadim00311 Посмотреть сообщение
Сделал вот так и все равно не работает
Конечно не работает, у вас при каждом добавлении мемка очищается.

И вообще, вы зря в поток это выносите, это очень легкий цикл, который отлично чувствовал бы себя в таймере. Тем более молотить вот так без перерыва в цикле вида while True do -- крайне дурной тон. Во первых вы нагрузите ядро процессора на 100% совершенно излишней работой (зачем вам мониторить окна 10000 раз в секунду?). А во вторых, ваш поток никогда не завершится, если уж крутить такой цикл, то он должен выглядеть так:
Delphi
1
2
3
4
5
while not Terminated do
  begin
    // тело цикла
    Sleep(500); // пауза в 0.5 секунды, незачем крутить чаще
  end;
0
17.10.2017, 16:22
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
17.10.2017, 16:22
Помогаю со студенческими работами здесь

Delphi. Ошибка в потоке
Здравствуйте. Такая штука. Не могу понять в чем проблема. В программе создаю поток, и все норм. Но...

Ошибка при работе в потоке
Писал софт с использованием многопоточности. В процедуре потока Execute возникла небольшая...

В чем ошибка в файловом потоке?
Есть программа. В файле borders.in такой текст: 6 6 2 1 1 4 4 3 3 6 6 . В файл borders.out...

Как получить значение переменной созданной в потоке, в другом потоке?
Добрый день :) Возник такой вопрос &quot;как получить значение переменной созданной в потоке, в другом...

Управление потоками. Изменение значения label (созданного в потоке 1) в потоке 2
Код таков: using System; using System.Collections.Generic; using System.ComponentModel; using...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru