Delphi idhttp потоки

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by CheatXX, 11 Sep 2010.

  1. CheatXX

    CheatXX New Member

    Joined:
    8 Jun 2009
    Messages:
    154
    Likes Received:
    2
    Reputations:
    0
    покажите пожалуйста пример работы с idhttp в потоках...
    мне выдает ошибку сокета когда делаю несколько потоков..
    каждому потоку нужно создавать свой ihttp? но как
    пример плз.
     
  2. Chrome~

    Chrome~ Elder - Старейшина

    Joined:
    13 Dec 2008
    Messages:
    937
    Likes Received:
    162
    Reputations:
    27
    Используй класс TThread и в событии Execute создавай idHTTP. Работай с ним, как тебе угодно. Ошибок не должно быть.
     
  3. 0pTik

    0pTik Banned

    Joined:
    18 Jul 2010
    Messages:
    240
    Likes Received:
    85
    Reputations:
    17
    Создавай динамически компонент вот и все )
     
  4. CheatXX

    CheatXX New Member

    Joined:
    8 Jun 2009
    Messages:
    154
    Likes Received:
    2
    Reputations:
    0
    как создавать idhttp в Execute
     
  5. Redeemer

    Redeemer Member

    Joined:
    3 Jul 2010
    Messages:
    203
    Likes Received:
    24
    Reputations:
    1
    idHttp := TIdHTTP.Create(nil);
     
  6. Chrome~

    Chrome~ Elder - Старейшина

    Joined:
    13 Dec 2008
    Messages:
    937
    Likes Received:
    162
    Reputations:
    27
    Значит так...
    Создаешь новый проект в Delphi.
    Дальше делаешь команду File => New => Other... и в появившемся окне выбираешь Thread Object.
    В появившемся окне пишешь название класса нового потока, которое должно начинаться с символа T. Например, TMyThread. Нажимаешь OK.
    В новом юните твоего потока подключаешь в uses модуль IdHTTP.
    Дальше это:
    Code:
    procedure TMyThread.Execute;
    begin
      { Place thread code here }
    end;
    Заменяешь на нужный тебе код. В данном случае сойдет такой вариант:
    Code:
    procedure TMyThread.Execute;
    var
      IdHTTP: TIdHTTP;
    begin
      IdHTTP := TIdHTTP.Create;
      IdHTTP.Get('http://yandex.ru');
      IdHTTP.Free;
    
      Terminate;
    end;
    Потом сохраняешь все юниты и проект. В основном юните подключаешь в uses модуль с описанием нашего потока.

    Добавляешь новую кнопку на форму и пишешь для нее например такое событие:
    Code:
    procedure TForm1.Button1Click(Sender: TObject);
    var
      Threads: array of TMyThread;
      i: Byte;
    begin
      SetLength(Threads, 10);
    
      for i := 0 to 9 do
      begin
        Threads[i] := TMyThread.Create(True);
        Threads[i].FreeOnTerminate := True;
        Threads[i].Resume;
      end;
    end;
    С помощью этого кода мы по одному разу загрузим страницу http://yandex.ru из каждого из 10 потоков.

    Данный код приведен для примера, надеюсь, сможешь разобраться.
     
    #6 Chrome~, 11 Sep 2010
    Last edited: 11 Sep 2010
  7. GhostOnline

    GhostOnline Active Member

    Joined:
    20 Dec 2008
    Messages:
    723
    Likes Received:
    110
    Reputations:
    22
    Нафига? =)
     
  8. Redeemer

    Redeemer Member

    Joined:
    3 Jul 2010
    Messages:
    203
    Likes Received:
    24
    Reputations:
    1
    Code:
    var
      Threads: TMyThread;
    begin
      Threads[i] := TMyThread.Create(True);
    
    Как?)))))

    На самом деле это просто опечатки
     
  9. 0pTik

    0pTik Banned

    Joined:
    18 Jul 2010
    Messages:
    240
    Likes Received:
    85
    Reputations:
    17
    Тут есть тема как работать с потоками, ищите
     
  10. Chrome~

    Chrome~ Elder - Старейшина

    Joined:
    13 Dec 2008
    Messages:
    937
    Likes Received:
    162
    Reputations:
    27
    Ну, это необходимо для очищения памяти занимаемой потоком. Поэтому я добавляю эту инструкцию в конец кода. А при инициализации потока я пишу:
    Code:
    Threads[i].[B]FreeOnTerminate[/B] := True;
    
    Чет я совсем не врубился, о каких опечатках идет речь. К тому же, именно тот код, который ты прокомментировал я не писал. Не понимаю, откуда ты это взял.

    Единая опечатка: вместо Threads: TMyThread; должно быть Threads: array of TMyThread;
     
  11. GhostOnline

    GhostOnline Active Member

    Joined:
    20 Dec 2008
    Messages:
    723
    Likes Received:
    110
    Reputations:
    22
    Дело в том что метод Terminate предназначен не для того чтобы его использовать внутри потока, потому как он просто ставит Terminated в True. Чтобы корректно завершать поток надо Terminate вызывать извне, а в потоке проверять на Terminted. Ты на это не проверяешь, по-этому смысла от Terminate вообще 0 )) и в потоке можно просто
    FTerminated := True;
    FreeOnTerminate вообще из другой оперы, и к Terminate отношения никакого не имеет
     
    1 person likes this.
  12. Redeemer

    Redeemer Member

    Joined:
    3 Jul 2010
    Messages:
    203
    Likes Received:
    24
    Reputations:
    1
    Именно про нее я и говорил. А код твой, просто я выкинул все не относящееся к делу.
     
  13. Chrome~

    Chrome~ Elder - Старейшина

    Joined:
    13 Dec 2008
    Messages:
    937
    Likes Received:
    162
    Reputations:
    27
    Ну лан. Будь добр, объясни мне тогда следующие явление. Я только что создал программу, в которой потоки создаются и автоматически уничтожаются по тому самому принципу, как и в коде выше. Только поток выполняет еще кучу ненужных операций в цикле, для наглядности примера. Вот ссылка на проект:
    Значит, после нажатия на кнопку в приложении, создается 100 дополнительных потоков. С помощью Диспетчера задач Windows мы видим, что размер оперативки занимаемой программой увеличивается. С помощью программы Spyware Process Detector я вижу, что действительно создаеться 100 дополнительных потоков. Через некоторое время (пару сек.) все потоки завершают цикл, соответственно и свою работу. В Spyware Process Detector видим, что у нас снова остаеться 1 единственный поток - главный. В Диспетчере задач Windows видим, что оперативки, занятой программой, стало меньше, а именно приблизительно столько, сколько было в момент запуска программы.
     
  14. GhostOnline

    GhostOnline Active Member

    Joined:
    20 Dec 2008
    Messages:
    723
    Likes Received:
    110
    Reputations:
    22
    И? :D
    Как это не согласуется с моими словами?
    Теперь удали из кода потока Terminate и прочувствуй разницу ;)
    А вернее, ее полное отсутствие
    Кстати, количество потоков запущенных программой можно смотреть и из Диспетчер задач Windows
     
  15. good_man

    good_man New Member

    Joined:
    24 May 2010
    Messages:
    112
    Likes Received:
    3
    Reputations:
    -2
    сори за оффтоп, хотел спросить у GhostOnline,

    как посмотреть потоки отдельного процесса? там все потоки в куче...
     
  16. Redeemer

    Redeemer Member

    Joined:
    3 Jul 2010
    Messages:
    203
    Likes Received:
    24
    Reputations:
    1
    Нельзя, это private-член. В стандартной реализации TThread (без frienship или herpers) вообще никак нельзя выставить эту переменную, это сделано для того, чтобы нельзя было ее поставить в False. В False ее вообще нельзя поставить.
     
  17. Redeemer

    Redeemer Member

    Joined:
    3 Jul 2010
    Messages:
    203
    Likes Received:
    24
    Reputations:
    1
    Вид -> Выбрать столбцы
     
    1 person likes this.
  18. GhostOnline

    GhostOnline Active Member

    Joined:
    20 Dec 2008
    Messages:
    723
    Likes Received:
    110
    Reputations:
    22
    http://s53.radikal.ru/i139/1009/26/41ca9a55d20c.png
    Terminated можно. Потоку в принципе без разницы

    Эхх, да Terminated только для чтения тут я не прав
    Но вызывать Terminate перед выходом из процедуры потока все равно смысла нет
     
    #18 GhostOnline, 11 Sep 2010
    Last edited: 11 Sep 2010
  19. Chrome~

    Chrome~ Elder - Старейшина

    Joined:
    13 Dec 2008
    Messages:
    937
    Likes Received:
    162
    Reputations:
    27
    Мне, честно говоря, нету особой разницы.
    Да, действительно. Я просто вроде как раньше видел какие то примеры работы с потоками, и там Terminate вызывался в конце кода (Вообще, уж не помню, откуда я это взял. Может быть и сам придумал, так как при работе программ не происходило никаких ошибок). Соглашаюсь, что не нужно Terminate вызывать в коде самого потока.
    Code:
    Чтобы корректно завершать поток надо Terminate вызывать извне
    Ну в данном случае при FreeOnTerminate он и так корректно завершается.
     
  20. good_man

    good_man New Member

    Joined:
    24 May 2010
    Messages:
    112
    Likes Received:
    3
    Reputations:
    -2
    Redeemer

    спасибо! респетую!)) вот я нуб ) не знал даже ) все время в прогах вывожу отдельную статистику ) ну там типа: запущен поток 1...запущен поток 2... :D