Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 6 293

/ вопрос закрыт /

Приветствую, уважаемые эксперты!

Я программирую в Delphi XE2, и столкнулся с глупой проблемой.
Проблема у меня с отдельным потоком, и циклом в нём.
А если точнее, то поток произвольно завершает свою работу, или зависает. (Не разобрался до сих пор)

Приложение:
  1.  
  2.  
  3. <code>
  4. TNewThread = class(TThread)
  5. private
  6. protected
  7. procedure Execute; override;
  8. public
  9. end;
  10. </code>
  11.  
  12. TNewThread.Create(false);</code>
  13.  
  14.  
  15. Stop:=True;</code>
  16.  
  17.  
  18. <code>
  19. procedure TNewThread.Execute;
  20. begin
  21. while not(Stop) do
  22. begin
  23. IdHTTP:=TidHTTP.Create(nil);
  24. IdHTTP.HandleRedirects:=True;
  25. try
  26. hash:=IdHTTP.Get('http://site.ru/1.php');
  27. except
  28.  
  29. Continue;
  30. end;
  31. r:=TRegExpr.Create;
  32. r.InputString:=hash;
  33. r.Expression:='<div class="post_text">(.*?)</div>';
  34. if r.Exec then
  35. begin
  36. text:=r.Match[1];
  37. text:=StringReplace(text,'&quot;','"',[rfReplaceAll]);
  38. end;
  39. r.Free;
  40.  
  41. if text='' then
  42. begin
  43.  
  44. Sleep(1000);
  45. Continue;
  46. end else if text>'' then begin
  47.  
  48. end;
  49. end;
  50.  
  51. end;
  52. </code>
  53.  
  54.  
  55.  
  56.  
  57.  
  58.  
  59.  
  60.  


Овчинников Алексей Иванович Вопрос закрыт (ответы не принимаются, мини-форум закрыт)

Вопрос задал: Овчинников Алексей Иванович (статус: Посетитель)
Вопрос отправлен: 26 октября 2012, 15:17
Состояние вопроса: закрыт, ответов: 0.


Мини-форум вопроса

Всего сообщений: 21; последнее сообщение — 30 октября 2012, 12:14; участников в обсуждении: 3.

Страницы: [1] [2] [Следующая »]

Мережников Андрей

Мережников Андрей (статус: Абитуриент), 26 октября 2012, 15:46 [#1]:

уж сколько раз твердили миру... не вставляйте в потоки обращения к элементам формы...
Овчинников Алексей Иванович

Овчинников Алексей Иванович (статус: Посетитель), 26 октября 2012, 15:50 [#2]:

А можно по подробней? Просто впервые вижу чтобы это могло бы быть причиной зависания.
А как тогда передавать информацию первой форме, если не обращаться к ней?
Овчинников Алексей Иванович

Овчинников Алексей Иванович (статус: Посетитель), 26 октября 2012, 15:54 [#3]:

Если что, класс потока, как и сам поток,находится на 1Юните. То есть, там-же, где и единственная форма.
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 26 октября 2012, 16:28 [#4]:

обработка реакции элементов формы идет в основном потоке программы и неважно в каком "юните" находится поток и форма. Обращаясь напрямую к элементу формы из отдельного потока - тормозите свой поток обработкой реакции элемента формы в основном потоке. Т.е. в таком случае полностью теряется смысл выделять какие-то действия в отдельный поток.

Цитата (Овчинников Алексей Иванович):

Просто впервые вижу чтобы это могло бы быть причиной зависания.

Давно с потоками работаете?

Цитата (Овчинников Алексей Иванович):

А как тогда передавать информацию первой форме, если не обращаться к ней?

через механизм сообщений. Почитайте о sendmessage и postmessage
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 26 октября 2012, 16:34 [#5]:

откройте любую книгу по Delphi, где описывается работа с потоками и посмотрите, что даже в самом простом примере для обращения к VCL компонентам используется метод synchronize. Если так необходимо это сделать. Но и этот метод - не панацея - поищите здесь на форуме в каком-то из вопросов Вадим К писал о применении метода synchronize. Не хочу заниматься плагиатом, поэтому не стану переписывать его слова.
Овчинников Алексей Иванович

Овчинников Алексей Иванович (статус: Посетитель), 26 октября 2012, 18:12 [#6]:

Попробовал использовать рекомендуемый вами метод - Synchronize

Т.е. Эту строку
Form1.Memo1.Lines.Append('['+TimeToStr(Now)+'] Нет команды.');

заменил на вот это:
Synchronize(procedure begin Form1.Memo1.Lines.Append('['+TimeToStr(Now)+'] Нет команды.'); end);

И вместо привычных 400-1200 запросов, программа отправила всего 100, и, затем, поток завис.
Может я что-то не верно делаю?
Наведите мне, пожалуйста, пример кода.
Овчинников Алексей Иванович

Овчинников Алексей Иванович (статус: Посетитель), 26 октября 2012, 18:15 [#7]:

Или покажите на примере всю процедуру Execute, как сделать в цикле добавление в мемо первой формы строку, дабы в результате поток не вис, буду очень благодарен.
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 26 октября 2012, 18:28 [#8]:

Цитата (Овчинников Алексей Иванович):

Попробовал использовать рекомендуемый вами метод - Synchronize

Я НЕ рекомендовал использовать synchronize. Я советовал прочитать про sendmessage и postmessage
Овчинников Алексей Иванович

Овчинников Алексей Иванович (статус: Посетитель), 26 октября 2012, 18:41 [#9]:

Мережников Андрей: Я НЕ рекомендовал использовать synchronize. Я советовал прочитать про sendmessage и postmessage


Извините, я, скорее всего, не так Вас понял.
Не могли бы вы навести пример как методами "sendmessage" и "postmessage", добавить в мемо строку. И ещё, если не сложно, как изменить свойство Caption в Label.
Это для статистики, каждый раз идёт такое:
kol_vo:=kol_vo+1;
Form1.Label1.Caption:=(IntToStr(kol_vo));
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 26 октября 2012, 18:55 [#10]:

вот ссылки на статьи про работу с сообщениями: http://cyberguru.ru/delphi/message-methods.html
http://citforum.ru/programming/32less/les19.shtml
а вот здесь http://www.rsdn.ru/forum/delphi/3754969.all что-то похожее на Ваш вопрос.
можно еще поискать, но думаю, что поиск можете сделать и сами.

в процедуре, обрабатывающей полученное из потока сообщение, можно нужно поместить все, что связано с обновлением компонентов формы.
Овчинников Алексей Иванович

Овчинников Алексей Иванович (статус: Посетитель), 26 октября 2012, 20:23 [#11]:

вот ссылки на статьи про работу с сообщениями: http://cyberguru.ru/delphi/message-methods.html
http://citforum.ru/programming/32less/les19.shtml
а вот здесь http://www.rsdn.ru/forum/delphi/3754969.all что-то похожее на Ваш вопрос.
можно еще поискать, но думаю, что поиск можете сделать и сами.
 
в процедуре, обрабатывающей полученное из потока сообщение, можно нужно поместить все, что связано с обновлением
компонентов формы.

Это всё конечно здорово, спасибо вам за линки да и вообще за то что Вы своё время тратите на меня, но я всё равно ничего не понял.
Раз Вы знаете как осуществить то что мне нужно, покажите на своём примере как это сделать, пожалуйста. Я бы был очень признателен. :-(
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 26 октября 2012, 20:38 [#12]:

утром поищу... если на ноутбуке есть, то отправлю... сейчас в отпуске и нет возможности поднять все исходники...
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 26 октября 2012, 20:58 [#13]:

вот пример передачи сообщений с помощью sendmessage из DelphiWorld
const
MY_MESSAGE = WM_USER + 4242;

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
// Handler that receive the Message
procedure MessageReceiver(var msg: TMessage); message MY_MESSAGE;
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var
txt: string;
begin
txt := 'Hello World';
SendMessage(Form1.Handle, MY_MESSAGE, 0, DWORD(PChar(txt)));
end;

// To receive this custom Message that is addressed to form1.handle
// you need a message handler.

procedure TForm1.MessageReceiver(var msg: TMessage);
var
txt: PChar;
begin
txt := PChar(msg.lParam);
msg.Result := 1;
ShowMessage(txt);
end;


end.

замените sendmessage на postmessage, иначе "тормоза" останутся
Овчинников Алексей Иванович

Овчинников Алексей Иванович (статус: Посетитель), 27 октября 2012, 02:29 [#14]:

>замените sendmessage на postmessage, иначе "тормоза" останутся
Сделал всё, как Вы посоветовали.
Использовал метод PostMessage, поток отправил ~850 гет запросов спустя 50 минут, а затем снова завис.
Отправлял сообщение в мемо следующим образом:
PostMessage(Form1.Handle, MY_MESSAGE, 0, DWORD(PChar('['+TimeToStr(Now)+'] Нет команды, ждём.')));

А вот процедура:
procedure TForm1.MessageReceiver(var msg: TMessage);
var
txt: PChar;
begin
txt := PChar(msg.lParam);
msg.Result := 1;
Memo1.Lines.Append(txt);
end;

SendMessage я тоже пробовал, результат идентичный с PostMessage, в чём же может быть проблема? Больше ничто не "дёргает" форму, всё остальное я убрал. Я в недоумении... :-(
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 27 октября 2012, 06:42 [#15]:

для чего вот эта строка находится в цикле:
IdHTTP:=TidHTTP.Create(nil); ???
и где освобождение памяти затем? При каждом выполнении тела цикла создается новый объект - занимает память, а освобождение памяти не происходит.
Овчинников Алексей Иванович

Овчинников Алексей Иванович (статус: Посетитель), 27 октября 2012, 09:38 [#16]:

Я уже сделал это, из цикла создавание ighttp я убрал(поместил перед циклом), и при условии что стоп будет равен True, сделал FreeAndNil(IdHTTP);.

Я удалил все обращения к форме, как и добавление информации, как и считывание её с ней, а затем, оставил программу работать на ночь. (Сам ушёл спать) Утром я проснулся, сел за компьютер, открыл сниффер (HTTP Analyzer V6) и что я вижу? Запросы отправляются до сих пор, даже сейчас, спустя 2 часа запросы отправляются без проблем и поток жив, что самое главное.
Я очень Вам благодарен, ведь, спустя целых 4 месяца, я наконец-таки понял почему вис этот бедный поток, огромное Вам спасибо! :-) Вы оказались правы с самого начала, поток вис именно из-за "любой" связи с формой.

Раньше я просто не заметил маленькой чепухи, а именно:
if pos('текст'+Form1.Edit10.Text, otvet) <>0 then begin
Как видите, было прямое обращение к компоненту формы и считывание с него информации. Ну эту проблему можно решить, я думаю, т.е. при нажатии на кнопку Старт сделать запись информации из нужных едитов в глобальные переменные, а затем отдельным потоком считывать информацию уже с переменных. Из-за этого ведь поток снова не зависнит?

И у меня к Вам ещё один вопрос, скорее всего что последний.
Допустим на 1 форме есть компонент Image и в него мне нужно загрузить капчу, если она, конечно, появляется на пути программы.
Как мне правильно осуществить это? Нет, создание самой картинки и загрузку в имейдж из файла я сделать могу, но как осуществить это правильно используя отдельный поток, чтобы при этом он не завис?
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 27 октября 2012, 09:52 [#17]:

на последний вопрос, к сожалению, ответить не могу - не использовал... я, в основном, занимаюсь работой с СУБД. С потоками пришлось столкнуться, когда писал программу по управлению раздаточными колонками на АЗС...
Овчинников Алексей Иванович

Овчинников Алексей Иванович (статус: Посетитель), 27 октября 2012, 21:24 [#18]:

Ясненько, Всё равно спасибо Вам! =)

Кстати, Андрей, почему только Вы отвечаете на мои вопросы? Другие эксперты ушли в зимнюю спячку, или что? :D
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 27 октября 2012, 21:30 [#19]:

Здесь каждый свободен отвечать на те вопросы, которые хочет :-) Обязанности отвечать нет.
Овчинников Алексей Иванович

Овчинников Алексей Иванович (статус: Посетитель), 28 октября 2012, 10:22 [#20]:

Уважаемые эксперты, будьте так добры и помогите глупцу с его проблемой. :-(

Страницы: [1] [2] [Следующая »]

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:58
Выполнено за 0.03 сек.