|
Вопрос # 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] [Следующая »]
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|