Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 03.02.2012, 16:05   #1
Shouldercannon
Участник клуба Подтвердите свой е-майл
 
Аватар для Shouldercannon
 
Регистрация: 26.01.2008
Сообщений: 1,897
Вопрос Получение данных в потоке через таймер

1. Подключиться через IdTCPClient1
2. В потоке через Timer получать данные
3. По событию формы Close остановить работу таймера и потока
Код:
...
  TMy_Thread = class(TThread)
  private
    { Private declarations }
    s: string;
  protected
    procedure Execute; override;
    procedure SyncProc;
  public
    GoMemo: TMemo;
  end;
...
procedure TFormMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Timer1.Enabled := False;

  if IdTCPClient1.Connected then IdTCPClient1.Disconnect;
end;

procedure TFormMain.BConnectClick(Sender: TObject);
begin
  IdTCPClient1.Host := '77.108.194.247';
  IdTCPClient1.Port := 80;
  IdTCPClient1.Connect(1000);

  Timer1.Enabled := True;
end;

procedure TFormMain.Timer1Timer(Sender: TObject);
var
  My_Thread: TMy_Thread;
begin
  My_Thread := TMy_Thread.Create(True);
  My_Thread.FreeOnTerminate := False;
  My_Thread.GoMemo := Memo1;
  My_Thread.Resume;
end;

procedure TMy_Thread.Execute;
begin
  if FormMain.IdTCPClient1.Connected then
  begin
    s := FormMain.IdTCPClient1.ReadLn();
    Synchronize(SyncProc);
  end;
end;

procedure TMy_Thread.SyncProc;
begin
  GoMemo.Lines.Add('[' + TimeToStr(Now) + '] - IdTCPClient1: ' + s);
end;
При закрытии формы появляется ошибка на строке
Код:
s := FormMain.IdTCPClient1.ReadLn();
Таймер завершает работу, а поток нет. Помогите, пожалуйста разобраться.
Изображения
Тип файла: jpg error.jpg (83.0 Кб, 123 просмотров)
Shouldercannon вне форума Ответить с цитированием
Старый 03.02.2012, 16:58   #2
Aliens_wolfs
Форумчанин
 
Регистрация: 16.12.2009
Сообщений: 902
По умолчанию

У вас таймер много потоков создает Да и зачем вам таймер когда все можно в потоке сделать примерно так, а можно все сделать чтобы в потоке создовался IdTCPClient1 и прием делать через событие
Код:
procedure TFormMain.BConnectClick(Sender: TObject);
var
  My_Thread: TMy_Thread;
begin
  IdTCPClient1.Host := '77.108.194.247';
  IdTCPClient1.Port := 80;
  IdTCPClient1.Connect(1000);

  My_Thread := TMy_Thread.Create(True);
  My_Thread.FreeOnTerminate := true; //Для самоуничтожения когда поток останавливается
  My_Thread.GoMemo := Memo1;
  My_Thread.Resume;
end;

//Затем крутите сам поток

procedure TMy_Thread.Execute;
begin
while not Terminated do
  begin
  if FormMain.IdTCPClient1.Connected then
  begin
    s := FormMain.IdTCPClient1.ReadLn();
    Synchronize(SyncProc);
end
else
begin
//Останавливается поток когда Disconnect
Synchronize(OnDisconnect); // Создайте эту функцию для того чтобы знать когда поток остановлен
Terminate;
end;
  end;

end;

Последний раз редактировалось Aliens_wolfs; 03.02.2012 в 17:09.
Aliens_wolfs вне форума Ответить с цитированием
Старый 03.02.2012, 17:09   #3
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Таймер и потоки - это как вилка и ложка. Вам надо или то или другое, но не оба сразу.

Опишите словами, что хотите получить.
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 03.02.2012, 17:14   #4
Aliens_wolfs
Форумчанин
 
Регистрация: 16.12.2009
Сообщений: 902
По умолчанию

GunSmoker Не поможешь с кодировкой в этой теме http://www.programmersforum.ru/showt...=185948&page=2
Aliens_wolfs вне форума Ответить с цитированием
Старый 03.02.2012, 17:23   #5
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Грязными делами не занимаюсь.
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 03.02.2012, 17:26   #6
Shouldercannon
Участник клуба Подтвердите свой е-майл
 
Аватар для Shouldercannon
 
Регистрация: 26.01.2008
Сообщений: 1,897
По умолчанию

Цитата:
Сообщение от GunSmoker Посмотреть сообщение
Таймер и потоки - это как вилка и ложка. Вам надо или то или другое, но не оба сразу.

Опишите словами, что хотите получить.
Получать данные в потоке от IdTCPClient1, дабы в обычно процедуре сие повесит форму.
Цитата:
Сообщение от Aliens_wolfs Посмотреть сообщение
Код:
//Останавливается поток когда Disconnect
Synchronize(OnDisconnect); // Создайте эту функцию для того чтобы знать когда поток остановлен
Не догоню. Что должно быть в этой функции и как она должна быть прописана (procedure/function;в теле потока или в самой форме)
Shouldercannon вне форума Ответить с цитированием
Старый 03.02.2012, 17:27   #7
Aliens_wolfs
Форумчанин
 
Регистрация: 16.12.2009
Сообщений: 902
По умолчанию

GunSmoker
Да там грязного ничего нет просто ссылка нужна человеку, которая грузит нормальный фильм с чистого сайта в Flash Media там видимо своя кодировка

Последний раз редактировалось Aliens_wolfs; 03.02.2012 в 17:40.
Aliens_wolfs вне форума Ответить с цитированием
Старый 03.02.2012, 17:30   #8
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

А таймер зачем сделали? Периодически хотите делать или как?
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 03.02.2012, 17:30   #9
Aliens_wolfs
Форумчанин
 
Регистрация: 16.12.2009
Сообщений: 902
По умолчанию

Shouldercannon
Как функцию в теле потока в ней какое либо событие когда IdTCPClient1.Connected=false например активировать обратно кнопку для следующего запроса, но можно и не делать
можно еще сделать не Synchronize(OnDisconnect) а destroy, тогда поток уничтожется но только после Terminate и тогда My_Thread.FreeOnTerminate := false;

Последний раз редактировалось Aliens_wolfs; 03.02.2012 в 17:39.
Aliens_wolfs вне форума Ответить с цитированием
Старый 03.02.2012, 17:38   #10
Shouldercannon
Участник клуба Подтвердите свой е-майл
 
Аватар для Shouldercannon
 
Регистрация: 26.01.2008
Сообщений: 1,897
По умолчанию

Цитата:
Сообщение от GunSmoker Посмотреть сообщение
А таймер зачем сделали? Периодически хотите делать или как?
Возможно, я ошибаюсь, но IdTCPClient1 не умеет работать в режиме приёма, как ClientSocket1Read, поэтому и приходится как-то (Timer) проверять, не пришли ли данные.

Код:
procedure TFormMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  if IdTCPClient1.Connected then IdTCPClient1.Disconnect;
end;

procedure TFormMain.BConnectClick(Sender: TObject);
var
  My_Thread: TMy_Thread;
begin
  IdTCPClient1.Host := '77.108.194.247';
  IdTCPClient1.Port := 80;
  IdTCPClient1.Connect(1000);

  My_Thread := TMy_Thread.Create(True);
  My_Thread.FreeOnTerminate := True; // Для самоуничтожения когда поток останавливается
  My_Thread.GoMemo := Memo1;
  My_Thread.Resume;
end;

procedure TMy_Thread.Execute;
begin
  while not Terminated do
  begin
    if FormMain.IdTCPClient1.Connected then
    begin
      s := FormMain.IdTCPClient1.ReadLn();
      Synchronize(SyncProc);
    end
    else
    begin
      // Останавливается поток когда Disconnect
      // Synchronize(OnDisconnect); // Создайте эту функцию для того чтобы знать когда поток остановлен
      Terminate;
    end;
  end;
end;

procedure TMy_Thread.SyncProc;
begin
  GoMemo.Lines.Add('[' + TimeToStr(Now) + '] - IdTCPClient1: ' + s);
end;
Беда, проблема с ошибкой осталась.

Цитата:
Сообщение от Aliens_wolfs Посмотреть сообщение
Shouldercannon
Как функцию в теле потока в ней какое либо событие когда IdTCPClient1.Connected=false например активировать обратно кнопку для следующего запроса, но можно и не делать
можно еще сделать не Synchronize(OnDisconnect) а destroy, тогда поток уничтожется но только после Terminate и тогда My_Thread.FreeOnTerminate := false;
Код:
procedure TMy_Thread.Execute;
begin
  while not Terminated do
  begin
    if FormMain.IdTCPClient1.Connected then
    begin
      s := FormMain.IdTCPClient1.ReadLn();
      Synchronize(SyncProc);
    end
    else
    begin
      Destroy;
    end;
  end;
end;
Имеете ввиду DoTerminate?

Последний раз редактировалось Shouldercannon; 03.02.2012 в 17:45.
Shouldercannon вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как правельно работать с событием в потоке через форму bulldog5293 Общие вопросы Delphi 13 16.08.2011 08:48
Таймер в потоке alexprey Общие вопросы Delphi 14 11.08.2010 23:14
Создать таймер в потоке? TwiX Общие вопросы Delphi 9 23.02.2010 21:39