Вынести функции в отдельные потоки Delphi

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by Rastamanka, 21 Mar 2012.

  1. Rastamanka

    Rastamanka Elder - Старейшина

    Joined:
    26 Nov 2008
    Messages:
    429
    Likes Received:
    11
    Reputations:
    7
    Доброе утро.
    Есть 2 функции.

    1) Отправка данных с помощью Synapse по https

    Code:
    function send_post(request,url_send,agent,cookie:string):string;
    var
      stream: TStringStream;
      BodyS: TStringList;
      begin
          HTTP := THTTPSend.Create;
    
            try
              HTTP.Document.Clear;
              HTTP.UserAgent := agent;
              HTTP.MimeType := 'application/x-www-form-urlencoded';
              HTTP.Headers.Add('Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' );
              HTTP.Headers.Add('AcceptLanguage: ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3');
              HTTP.Headers.Add('Referer: http://'+Trim(Setting.edt4.Text)+'/game.php');
              HTTP.Cookies.Text:=cookie;
              stream:=TStringStream.Create('');
              stream.WriteString(request);
    
              HTTP.Document.LoadFromStream(stream);
    
              if (request<>'') then
              HTTP.HTTPMethod('post',url_send)
              else
              HTTP.HTTPMethod('get',url_send);
    
              BodyS := TStringList.Create;
              BodyS.LoadFromStream(HTTP.Document);
    
              Result:=BodyS.Text;
    
          finally
            HTTP.Free;
    
            end;
    
      end;
    
    2) Отправка данных с помощью Indy по http используя cookie

    Code:
    function send(nick,textmes:string):string;
    var
      s:string;
    begin
    
        s:='prv['+nick+'] '+textmes;
        s:=AnsiToUtf8(s);
        s:=UrlEncode(s,False);
        s:=Trim(s);
        s:= send_post('','http://'+Trim(Setting.edt4.Text)+'/srv/chat/chat_proc?wChannel=1&locID='+Trim(lock)+'&msgID='+Trim(id)+'&xml=1&msgPrvID=0&lChannel=15&textMsg='+s,'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:11.0) Gecko/20100101 Firefox/11.0',cookie);
     
    end;
    
    Подскажите как вынести обработку каждой из этих функций в отдельные потоки?
     
  2. mironich

    mironich Elder - Старейшина

    Joined:
    27 Feb 2011
    Messages:
    733
    Likes Received:
    73
    Reputations:
    19
    BeginThread
    Tthread
     
  3. Rastamanka

    Rastamanka Elder - Старейшина

    Joined:
    26 Nov 2008
    Messages:
    429
    Likes Received:
    11
    Reputations:
    7
    А по подробней можно?
     
  4. mironich

    mironich Elder - Старейшина

    Joined:
    27 Feb 2011
    Messages:
    733
    Likes Received:
    73
    Reputations:
    19
    http://grabberz.com/showthread.php?t=24619
     
  5. Rastamanka

    Rastamanka Elder - Старейшина

    Joined:
    26 Nov 2008
    Messages:
    429
    Likes Received:
    11
    Reputations:
    7
    Как в BeginThread передать параметры функции? Вот мне надо запустить функцию send и передать ей параметры nick,textmes. Погуглив не найден ответ как сразу 2 параметра передать.
     
  6. mironich

    mironich Elder - Старейшина

    Joined:
    27 Feb 2011
    Messages:
    733
    Likes Received:
    73
    Reputations:
    19
    В статье ссылку на которую я дал есть момент где расписано как.
     
  7. alexey-m

    alexey-m Elder - Старейшина

    Joined:
    15 Jul 2009
    Messages:
    518
    Likes Received:
    100
    Reputations:
    37
    параметры передаются через указатель на структуру, где эти параметры хранятся
    наглядно можно посмотреть тут
     
  8. sn0w

    sn0w Статус пользователя:

    Joined:
    26 Jul 2005
    Messages:
    1,021
    Likes Received:
    1,200
    Reputations:
    327
    typedef struct _tMyData
    {
    void *buffer;
    size_t bufferLen;
    char s_auxpayload[128];
    }MYDATA, *PMYDATA;

    ///...///
    PMYDATA pmd = (PMYDATA)malloc(sizeof(MYDATA));
    pmd->buffer = ...
    CreateThread(...pmd...);

    еще же есть TLS;
    __declspec(thread) int myVarThreadSpecific;
     
  9. Rastamanka

    Rastamanka Elder - Старейшина

    Joined:
    26 Nov 2008
    Messages:
    429
    Likes Received:
    11
    Reputations:
    7
    Подскажите правильно ли все сделано?
    Вроде сделано в отдельный поток. Но при отправке окно главной программы подвисает все равно. Хотя по сути раз происходит отправка в потоке этого не должно происходить.

    1) Сверху добавили тип
    Code:
     type
      TMyThread1 = class(TThread)
       private
         { Private declarations }
       protected
         procedure addanswer;
         procedure Execute; override;
       end;
    
    2) Ниже обозначили переменную
    Code:
    var   T1: TMyThread1;
    
    3) Добавили процедуру отправки данных
    Code:
    procedure TMyThread1.addanswer;
      var
       request:string;
       HTTP1:THTTPSend;
       stream: TStringStream;
       BodyS: TStringList;
     begin
    
             request:='log=answer&comp_name='+comp_name+'&add_question='+Form1.edt1.Text+'&add_answer='+Form1.edt3.Text+'&';
    
            if(Form1.chk2.Checked=True) then
               request:=request+'add_race=2'
            else if(Setting.rb1.Checked=True) then
               request:=request+'add_race=0'
            else if(Setting.rb2.Checked=True) then
               request:=request+'add_race=1';
    
             HTTP1 := THTTPSend.Create;
    
            try
              HTTP1.Document.Clear;
              HTTP1.UserName:=Trim(Form1.edt2.Text);
              HTTP1.Password:=Trim(Form1.edt4.Text);
              HTTP1.UserAgent := 'Mozilla Firefox 3.11';
              HTTP1.MimeType := 'application/x-www-form-urlencoded';
              HTTP1.Headers.Add('Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' );
              HTTP1.Headers.Add('AcceptLanguage: ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3');
              HTTP1.Headers.Add('Referer: http://google.com');
              stream:=TStringStream.Create('');
              stream.WriteString(request);
    
              HTTP1.Document.LoadFromStream(stream);
    
              HTTP1.HTTPMethod('post',host+'/answer/');
    
              BodyS := TStringList.Create;
              BodyS.LoadFromStream(HTTP1.Document);
              Form1.stat1.Panels[0].Text:=BodyS.Text;
    
              Form1.edt3.Text:='';
    
          finally
            HTTP1.Free;
            T1.Terminate;
            end;
     end;
    
    
    4) Добавили Execute
    Code:
    procedure TMyThread1.Execute;
    begin
     Synchronize(addanswer);
    end;
    
    5) Запуск потока
    Code:
    procedure TForm1.pressKey(Sender: TObject; var Key: Char);
    begin
    
    if Key = #13 then
      if(edt3.Text<>'') then
      begin
        if(edt1.Text<>'') then
          begin
    
             T1 := TMyThread1.Create(False);
             T1.Priority := tpLowest;
    
          end;
         
    
        end;
    
    end;
    
     
  10. cheater_man

    cheater_man Member

    Joined:
    13 Nov 2009
    Messages:
    651
    Likes Received:
    44
    Reputations:
    7
    _http://www.delphi-manual.ru/synchronize.php
     
  11. Rastamanka

    Rastamanka Elder - Старейшина

    Joined:
    26 Nov 2008
    Messages:
    429
    Likes Received:
    11
    Reputations:
    7
    Спасибо буду знать. Если правильно понимаю. То необходимо просто убрать synchronize чтобы работа шла в отдельном от главного потока?
     
  12. cheater_man

    cheater_man Member

    Joined:
    13 Nov 2009
    Messages:
    651
    Likes Received:
    44
    Reputations:
    7
    Все предельно просто. в execute код потока, synchronize вызываем тогда, когда нужо обновить какой-то компонент. Еще посмотри про критические секции