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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 11.02.2012, 01:13   #1
The SCS
Пользователь
 
Регистрация: 15.01.2012
Сообщений: 98
Печаль Вынесение функции в отдельный поток

В моей программе по действию таймера (каждые 10 сек) с сервера загружается список игровых серверов. На медленных соединениях это вызывает жуткие тормоза, а иногда программа виснет полностью, вдобавок к этому работает VortexIRC, активность на канале большая. И вот приложение пытается обновить список серверов, получить от сервера юзерлист и прочее. Неудивительно, что на медленных соединениях программа быстро и намертво повисает.

Прочитал про потоки. Вроде сделал, но оно то не обновляется, то обновляется один раз, и потом программа виснет, вобщем чушь получается.

Помогите вынести все из процедуры TfrmMain.tmrGamesTimer в отдельный поток

Исходники есть тут, но чтоб открыть, скомпилить нужна туева хуча компонентов.
The SCS вне форума Ответить с цитированием
Старый 11.02.2012, 01:22   #2
The SCS
Пользователь
 
Регистрация: 15.01.2012
Сообщений: 98
По умолчанию

Вроде ж все правильно сделал, но после выполнения потока программа виснет намертво. Вот исходник

Код:
unit updategames;

interface

uses
  Classes, SysUtils;

type
  TWords = class
  private
    FText: string;
    FWords: TStringList;
    procedure Parse;
    function GetWord(Index: Integer): string;
    procedure SetText(const Value: string);
    function GetCount: integer;
  public
    constructor Create;
    destructor Destroy; override;
    function ConcatToEnd(From: integer): string;
    property Text: string
      read  FText
      write SetText;
    property Words[Index: Integer]: string
      read  GetWord;
      default;
    property Count: integer
      read  GetCount;
  end;

  TUpdThread = class(TThread)
  private
    { Private declarations }
  protected
    procedure Execute; override;
  end;


implementation

uses mainform, loginform;

{ Important: Methods and properties of objects in visual components can only be
  used in a method called using Synchronize, for example,

      Synchronize(UpdateCaption);

  and UpdateCaption could look like,

    procedure TThread.UpdateCaption;
    begin
      Form1.Caption := 'Updated in a thread';
    end; }

{ UpdThread }

constructor TWords.Create;
begin
  inherited;
  FWords := TStringList.Create;
end;

destructor TWords.Destroy;
begin
  FWords.Free;
  inherited;
end;

function TWords.GetCount: integer;
begin
  Result := FWords.Count;
end;

function TWords.GetWord(Index: Integer): string;
begin
  if index >= Count then
    Result := ''
  else
    Result := FWords[index];
end;

procedure TWords.Parse;
var
  i: integer;
  w: string;
begin
  FWords.Clear;
  w := '';
  for i := 1 to Length(FText) do
  begin
    case FText[i] of
    #9, #10, #13, #32: // whitespace
      if w <> '' then
      begin
        FWords.Add(w);
        w := '';
      end;
    else
      w := w + FText[i]
    end;
  end;
  if w <> '' then
    FWords.Add(w);
end;

procedure TWords.SetText(const Value: string);
begin
  if Value <> FText then
  begin
    FText := Value;
    Parse;
  end;
end;

function TWords.ConcatToEnd(From: integer): string;
var
  i: integer;
begin
  result := '';
  for i := From to Count-1 do
  begin
    if i <> From then
      Result := Result + ' ';
    Result := Result + Words[i];
  end;
end;


procedure TUpdThread.Execute;
var
W: TWords;
Sl: TStringList;
I, ITemp: Integer;
begin
  Sl := TStringList.Create;
  W := TWords.Create;
   try
     Sl.Text := frmmain.http.Get('http://'+frmLogin.cbServer.Text+'/wormageddonweb/GameList.asp?Channel='+StringReplace(frmLogin.cbchan.Text,'#','',[]));
     Itemp := gmfrm.lvGames.ItemIndex;
     gmfrm.lvGames.Clear;
   //  gmfrm.lvGames.Items.BeginUpdate;
     for I := 1 to Sl.Count-2 do begin
        if Pos('<GAMELIST',Sl[I]) = 0 then
        if Sl[I] <> '' then begin
          W.Text := Sl[I];
          with gmfrm.lvGames.Items.Add do begin
           if W[6] = '1' then
            ImageIndex := 63
           else
            ImageIndex := 62;
           SubItemImages[Subitems.Add('')] := StrToInt(W[4]);
           SubItems.Add(W[1]);
           SubItems.Add(W[2]);
           SubItems.Add(W[3]);
           SubItems.Add(W[7]);
          end;
        end;
      end;
    //  gmfrm.lvGames.Items.EndUpdate;
      gmfrm.lvGames.ItemIndex := Itemp;
   except
   end;
  W.Free;
  Sl.Free;
  Synchronize(Execute);
end;

end.
В таймере прописано:

Код:
var
  u: TUpdThread;
begin
  u:=TUpdThread.Create(False);
  u.FreeOnTerminate:=true;
The SCS вне форума Ответить с цитированием
Старый 11.02.2012, 01:27   #3
The SCS
Пользователь
 
Регистрация: 15.01.2012
Сообщений: 98
По умолчанию

Вот что я за человек. До того как не поделюсь проблемой на форуме решение до меня не дойдет

Убрал
Код:
Synchronize(Execute);
, заработало.

Всетаки потоки это вещь
Модеры, если посчитаете тему лишней, удалите.
The SCS вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Вынести GUI в отдельный поток Silly Student C++ Builder 1 22.11.2011 15:15
ОтДельный поток StartMis Общие вопросы Delphi 10 22.02.2010 08:20
Создать отдельный поток для отправки письма betirsolt Работа с сетью в Delphi 2 28.12.2009 22:39
Отсылка почты через отдельный поток Hottabych Работа с сетью в Delphi 16 15.03.2008 11:31
Отсылка почты через отдельный поток Hottabych Работа с сетью в Delphi 0 11.03.2008 19:32