| 
| 
 | Вопрос # 6 293/ вопрос закрыт / | 
 |  Приветствую, уважаемые эксперты!
 Я программирую в Delphi XE2, и столкнулся с глупой проблемой.
 Проблема у меня с отдельным потоком, и циклом в нём.
 А если точнее, то поток произвольно завершает свою работу, или зависает. (Не разобрался до сих пор)
 Приложение:Переключить в обычный режим   <code>  TNewThread = class(TThread)  private  protected    procedure Execute; override;  public  end;</code> TNewThread.Create(false);</code>  Stop:=True;</code>  <code>procedure TNewThread.Execute;begin  while not(Stop) do    begin      IdHTTP:=TidHTTP.Create(nil);      IdHTTP.HandleRedirects:=True;      try        hash:=IdHTTP.Get('http://site.ru/1.php');       except       Continue;      end;      r:=TRegExpr.Create;      r.InputString:=hash;      r.Expression:='<div class="post_text">(.*?)</div>';      if r.Exec then         begin          text:=r.Match[1];          text:=StringReplace(text,'"','"',[rfReplaceAll]);         end;      r.Free;         if text='' then          begin            Sleep(1000);           Continue;        end else if text>'' then begin         end;       end; end;</code>        
|  |   Вопрос задал: Овчинников Алексей Иванович (статус: Посетитель)Вопрос отправлен: 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, 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]:Ясненько, Всё равно спасибо Вам! =) 
 Кстати, Андрей, почему только Вы отвечаете на мои вопросы? Другие эксперты ушли в зимнюю спячку, или что?
   |  
|   | Мережников Андрей (статус: Абитуриент), 27 октября 2012, 21:30 [#19]:Здесь каждый свободен отвечать на те вопросы, которые хочет  Обязанности отвечать нет. |  
|   | Овчинников Алексей Иванович (статус: Посетитель), 28 октября 2012, 10:22 [#20]:Уважаемые эксперты, будьте так добры и помогите глупцу с его проблемой.   |  Страницы: [1] [2] [Следующая »]  Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте. |