Форум программистов, компьютерный форум, киберфорум
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.54/26: Рейтинг темы: голосов - 26, средняя оценка - 4.54
0 / 0 / 0
Регистрация: 14.07.2015
Сообщений: 34

Delphi XE8 параллельные потоки

19.07.2015, 18:38. Показов 6298. Ответов 42
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день!

У меня есть две процедуры, первая
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
51
52
53
Procedure TForm1.BConnectClick(Sender: TObject);
var
i, e, cnt, LastNewsWorking : integer;
EF : TXLSFile;
Archivesg:TStringGrid;
key, FileToOpen : string;
begin
  isi.Host:=LES.Text;
  isi.Port:=2000;
  isi.Destination:=isi.Host+':2000';
  sb.Panels.Items[0].Text:='';
  sb.Panels.Items[4].Text:='';
  for i := 0 to 5 do sg.Cols[i].Clear;
  if KeepAliveHelo.Enabled=true then KeepAliveHelo.Enabled:=false;
  if GetDataTimer.Enabled=true then GetDataTimer.Enabled:=false;
  cnt:=strtoint(LEdit.Text);
  SetFormat(sg);  //готовим SG
  ToConnect('rus', 120);
  GetHISN(cnt);  // получаем заголовки;
  sb.Panels.Items[0].Text:='Соединение активно, режим ожидания';
  FileToOpen := BasePath + '\' + copy(AnsiReplaceText(sg.Cells[3,1],'/','.'),4,7) + '.xls';
  if FileExists(FileToOpen) = true then LoadMessageFileOrServer(FileToOpen)
    else begin
      FileToOpen := BasePath + '\' + copy(AnsiReplaceText(sg.Cells[3,sg.RowCount-1],'/','.'),4,7) + '.xls';
      if FileExists(FileToOpen) then LoadMessageFileOrServer(FileToOpen)
         else LoadAllBodyNewsFromServer(sg, cnt);
    end;
  // проверяем поле емайл, если пустое, обрабатываем сообщение
{******************************************************************************}
  TaskSendEmail := TTask.Create(procedure()
                   var i : integer;
                   begin
                     for i := 1 to cnt do begin
                        if sg.Cells[6,i] = '' then begin
                          if (AnsiPos('NT: *', sg.Cells[4,i])>0) or
                             ((AnsiPos('NT: News:', sg.Cells[4,i])>0) and
                             (AnsiPos(UpperCase('microsoft'), UpperCase(sg.Cells[5,i])) > 0)) then begin
                             sg.Cells[6, i] := SendTransport('email@email.ru', sg.Cells[1,i] + ' - ' + sg.Cells[4,i],
                             '<div align="right">' + sg.Cells[1,i] + '</div>' +
                             sg.Cells[3,i] + '  ' + sg.Cells[2,i] + '<br><br>' +
                             '<b>' + sg.Cells[4,i] + '</b><br>' +
                             '<div align="justify">' + sg.Cells[5,i] + '</div>');
                          end else sg.Cells[6, i] := 'обработанно';
                        end;
                     end;
                   end);
  TaskSendEmail.Start;
{******************************************************************************}
  LEFPath.EditLabel.Caption:='Загрузка успешно выполненна';
  if TimerForProgressBar.Enabled=false then TimerForProgressBar.Enabled:=true;
  if KeepAliveHelo.Enabled=false then KeepAliveHelo.Enabled:=true;
  if GetDataTimer.Enabled=false then GetDataTimer.Enabled:=true;
end;
TaskSendEmail объявленна глобально как TaskSendEmail: ITask; Первая процедура создает при определенных условиях параллельный поток, результаты выполнения этого потока в программе нигде не жду, поток просто отправляет письма на емаил и все

Во второй процедуре (ниже) я проверяю состояние этого потока, строку выделил, в этой строке если поток не выполняется мне нужно выполнить указанные действия
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
procedure TForm1.ReadOnlineData();
var
sss:string;
i, cnt:integer;
begin
  try
    repeat
      sss:=isi.ReadLn(#13#10,IndyTextEncoding_OSDefault);
      if (sss<>'') and (Pos('TC:', sss)=0) then ListNews.Add(sss);
    until sss<>'';
{******************************************************************************}
    if TaskSendEmail.Status <> TTaskStatus.Running then begin
{******************************************************************************}
      sb.Panels.Items[0].Text:='Получение данных';
        if listnews.Count>0 then begin
        isi.writeln('STOP');
        isi.Readln(#13#10);
        cnt:=ListNews.Count-1;
          for i:=0 to cnt do begin
          InsertFirstRow(sg,RebrendNews(ListNews[i],1),0);
          if sg.Cells[1,1]<>'' then isi.writeln('GET '+sg.Cells[1,1])
            else showmessage('Пустой номер сообщения. Строка = 1, Столбец = 1. Метод GET невозможен');                      //запрашиваем
          sss:=isi.Readln(inttostr(strtoint64(sg.Cells[1,1]))+#13#10);
          if pos('BAD ',sss)>0 then showmessage('Сервер сообщил об ошибке в запрос GET. Запрос GET '+sg.Cells[1,1] + '; Ответ: ' + sss);
          sss:=isi.Readln('.'+#13#10,IndyTextEncoding_OSDefault);
          sss:=AnsiReplaceText(sss,Chr(13)+Chr(10),'');  //удаляем первые две пустые строки
          sss:=AnsiReplaceText(AnsiReplaceText(AnsiReplaceText(sss,'\r\n\r\n','\r\n'), '\r',Chr(13)),'\n',Chr(10));//меняем \r\n на новую строку (№13№10)
          sg.Cells[5,1]:=sss;
          GetNewsForEmail(sg, 1);
          end;
          ListNews.Clear;
          isi.writeln('STAR');
          isi.Readln(#13#10);
          isi.WriteLn('HELO');  //-
          isi.ReadLn(#13#10);  //-
          sb.Panels.Items[0].Text:='Соединение активно, режим ожидания';
        end;
    end;
  except
    ListNews.Clear;
    sb.Panels.Items[4].Text:='Ошибка';
    sb.Panels.Items[0].Text:='Соединение прекращенно';
    if isi.connected=true then isi.Close;
    if ilf.Active then ilf.Active:=false;
    for i:= 1 to sg.RowCount-1 do if sg.Cells[1,i]='' then delrow(sg,i);
    ToConnect('rus',120);
  end;
end;
Проблема в том, что не зависимо от того выполняется поток или нет, я никогда не попадаю во второй процедуре в код после жирной строки. Подскажите что не так?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
19.07.2015, 18:38
Ответы с готовыми решениями:

Параллельные потоки с параметром Delphi
Есть задача: Есть 3 потока. Есть параметр k. Когда поток получает параметр, он начинает заполнять progressbar, до тех пор пока другой поток...

ОС на Delphi XE8
Всем привет! У меня есть вопрос! Могу ли я, если могу то как, сделать ОС на Delphi XE8! Позырил кучу форумов! Кто-то говорит можно,...

Delphi xe8 моргает
Подскажите, из-за чего может моргать изображение при repaint? И моргает именно на ноутбуке, на стационарах (достаточно старых) не моргает...

42
3530 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
02.08.2015, 20:23
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от mister88888 Посмотреть сообщение
там под тысячу строк кода
Это подключение что ли тысяча строк ?!
Что ж ты там такого понахреновертил, что простейшая в общем операция вылилась в целый опус ?)
0
0 / 0 / 0
Регистрация: 14.07.2015
Сообщений: 34
02.08.2015, 20:47  [ТС]
ты мне лучше скажи, все таки как мне быть с нитью, если я пере подключаю сокет в основном потоке, мне нужно нить заного создавать, и передавать ей сокет или со старой тоже сойдет?
0
3530 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
02.08.2015, 20:59
Ну нельзя заниматься манипуляциями с подключением-отключением в одной нити, в то время как другая, ничего не зная об этом, продолжает мочалить сокет приемопередачами)

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

Синхронизацией это называется.
0
0 / 0 / 0
Регистрация: 14.07.2015
Сообщений: 34
02.08.2015, 21:06  [ТС]
может я не корректно вопрос поставил, просто с этим программированием про все забываешь...
Смотри, у меня подключение в основном потоке происходит
Дальше запускается нить для обмена данными с сервером, в которую передается параметром переменная с подключенным сокетом.
Если в нити возникает ошибка, я ее гашу в нити, и передаю управление основному потоку в котором делаю реконнект, при этом нить у меня остается, просто в ней процедура execute завершается.
Вопрос у меня в том, что после реконекта в основном потоке, мне существующую нить нужно убивать и создавать заного или просто запустить ее опять и она сама найдет(!) туже переменную с сокетом
0
3530 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
02.08.2015, 21:09
Цитата Сообщение от mister88888 Посмотреть сообщение
передаю управление основному потоку
Это как ?
Все то время пока доп.поток работает, основной у тебя ждет что ли пока тот завершится ?
0
0 / 0 / 0
Регистрация: 14.07.2015
Сообщений: 34
02.08.2015, 21:15  [ТС]
нет не ждет, просто в основном потоке после подключения никакого обращения к сокету не происходит, он занимается обработкой интерфейса по запросам пользователя. Блин я вот сейчас пишу и думаю, и вправду логичней в доп потоке делать и коннект и с данными работать и дисконект, но я создавал доп поток только ради того чтобы он раз в в 3 минуты отправлял на сервер запрос NOOP и проверял нет ли от сервера новых данных
0
3530 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
02.08.2015, 21:17
Цитата Сообщение от mister88888 Посмотреть сообщение
создавал оп поток только ради того чтобы он раз в в 3 минуты отправлял на сервер запрос NOOP и проверял нет ли от сервера новых данных
Ну а кроме этого NOOP какой-то еще обмен с сервером разве не выполняется ?
В каком потоке это происходит ?
0
0 / 0 / 0
Регистрация: 14.07.2015
Сообщений: 34
02.08.2015, 21:25  [ТС]
Цитата Сообщение от mss Посмотреть сообщение
Ну а кроме этого NOOP какой-то еще обмен с сервером разве не выполняется ?
В каком потоке это происходит ?
весь обмен данными в доп потоке, отправка NOOP, чтение ответа, поиск в ответах новой информации все это в доп потоке, кроме коннект/дисконнект

Добавлено через 6 минут
давай с другой стороны задам вопрос.
Если я создаю сокет в переменную А, потом копирую переменную А -> в У. Далее в переменной А отключаю сокет и подключаю. У меня переменные А и У одинаковые будут или разные?
0
3530 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
02.08.2015, 21:27
Тогда тем непонятнее нафих нужен коннект-дисконнект в осн.потоке, если львиная доля логики обмена осуществляется именно в доп.потоке ..

Но в любом случае факт завершения метода Execute доп.нити означает невозможность повторного ее использования.
1
0 / 0 / 0
Регистрация: 14.07.2015
Сообщений: 34
02.08.2015, 21:28  [ТС]
Цитата Сообщение от mss Посмотреть сообщение
Но в любом случае факт завершения метода Execute доп.нити означает невозможность повторного ее использования.
Вот это и хотел узнать
0
3530 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
02.08.2015, 21:28
Цитата Сообщение от mister88888 Посмотреть сообщение
У меня переменные А и У одинаковые будут или разные?
Конечно одинаковые.. Ты же нигде после копирования не изменяешь содержимое ни той ни другой переменной ..
0
0 / 0 / 0
Регистрация: 14.07.2015
Сообщений: 34
13.09.2015, 18:56  [ТС]
Цитата Сообщение от mss Посмотреть сообщение
Примеры примерами, но подумать-то надо) .. Над тем кто в данном случае является Self'ом..
Привет! А можешь все же пояснить что мне вместо Self-а ставить
Delphi
1
2
3
4
procedure TheTH.OnTerminate(Sender: TObject);
begin
  FreeAndNil(Self)
end;
Я не могу понять назначение оператора Self!?
0
3530 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
13.09.2015, 21:02
Цитата Сообщение от mister88888 Посмотреть сообщение
что мне вместо Self-а ставить
Ничего не ставить.
Нельзя так делать - уничтожать объект в обработчике его же собственного события.
0
0 / 0 / 0
Регистрация: 14.07.2015
Сообщений: 34
13.09.2015, 21:11  [ТС]
А где же его уничтожать тогда?
0
3530 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
13.09.2015, 21:14
Странно при этом что ты не задаешь вопрос "где его создавать"..
Вот там где создавал - там и уничтожай.
0
0 / 0 / 0
Регистрация: 14.07.2015
Сообщений: 34
13.09.2015, 21:24  [ТС]
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
type
  TheTH= class(TThread)
  private
  gserv:TIdIOHandlerStack;
  CountServerCall:integer;
  protected
    procedure Execute; override;
  public
    constructor Create(serv:TIdIOHandlerStack);
    procedure OnTerminate(Sender: TObject);
end;
 
constructor TheTH.Create(serv:TIdIOHandlerStack);
begin
  inherited Create(True);
   gserv:=serv;
end;
вот так создавал. Ты имеешь ввиду писать в секции public destructor и в нем прописывать FeeAdNil() ?
0
3530 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
13.09.2015, 21:26
Где у тебя создается экземпляр класса TheTH ?
0
0 / 0 / 0
Регистрация: 14.07.2015
Сообщений: 34
13.09.2015, 21:34  [ТС]
Delphi
1
2
3
4
5
  if TheTHWork= nil then begin
    TheTHWork:= TheTH.Create(gserv);  //создаем поток TheTH
    TheTHWork.Priority := tpNormal;
    TheTHWork.FreeOnTerminate := false;
    TheTHWork.Start;
код привязан к кнопке TButton
0
3530 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
13.09.2015, 21:38
Цитата Сообщение от mister88888 Посмотреть сообщение
код привязан к кнопке TButton
А кнопка - это объект формы.
И обработчик события кнопки - это метод формы.

Вот и уничтожай поток точно там - в любом подходящем методе-обработчике любого подходязего объекта на форме. Или в обработчике какого-то события самой формы.
0
0 / 0 / 0
Регистрация: 14.07.2015
Сообщений: 34
13.09.2015, 22:08  [ТС]
А как уничтожать через TheTHWork.Destroy или FreeAndNil(TheTHWork) ?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
13.09.2015, 22:08

Как активировать Delphi xe8?
Запуск от имени администратора не помогает(

Не открывается проект в Delphi XE8
Ребята, вот есть готовый проект. На ранних версиях XE работает. На XE5 и выше не работает. Не знаю уже даже что и делать. Кто опытнее...

Возможности и преимущества среды delphi xe8
Кто нибудь может рассказать об delphi xe8, о его особенностях и возможностях , или ссылки на ресурсы , желательно русскоязычные.

Не могу установить ZLibExGZ Delphi XE8
В общем проблема в шапке, может кто помочь ?. Лучше если есть у кого-то мануал по установке.

CodeSite в Delphi XE8, не работает CodeSiteLogging
Скажите, почему при подключении модуля CodeSiteLogging, Delphi его не находит?


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
Нашел вот забавное видео о измерениях. Лучшее что я видел на эту тему
kumehtar 26.08.2026
ILETXiw9bMQ Основная суть и тезисы по измерениям: 0D (Нулевое измерение): точка, не имеющая длины, ширины, высоты или объема. Объект не может перемещаться в 0D. 1D (Первое измерение):. . .
[EasyBuilder Pro] Памятка по разработке для панелей Weintek
ФедосеевПавел 26.08.2026
Памятка по разработке для панелей Weintek ВВЕДЕНИЕ Ранее, при реализации проектов основное внимание уделял разработке управляющей программы для контроллера, а панели оператора доставалось время. . .
Модель по догадкам
anaschu 25.08.2026
Прошло две недели. Я уже рассказывал, как разговаривал с сотрудниками у сортировки и как понял, что главная ветка — не про приёмку, а про отбор. Но тогда я думал, что понял механику. На этой неделе я. . .
Запись в регистр сведений независимо от заполненности табличной части
Maks 25.08.2026
Реализация из решения ниже выполнена на нетиповом документе с несколькими табличными частями, разработанного в КА2. Задача: Обеспечить запись документа в регистр сведений независимо от. . .
Ноутбук Альфария
kumehtar 24.08.2026
Встретился тут в сети ноутбук Альфария, примарха Альфа-Легиона. Хотя возможно, это ноутбук Омегона, разумеется. Ну как вам?
Мастера простых решений
DevAlt 23.08.2026
В сишарп стэках winforms, да и wpf существует сложная система связывания источниках данных и элементов формы(текстовые поля и метки), опирается все это на технологию событий и мета. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru