Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Потоки в DLL 
:(
    Опции темы
aktuba
  Дата 2.2.2007, 08:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Смышленный
***


Профиль
Группа: Завсегдатай
Сообщений: 1915
Регистрация: 24.4.2006
Где: Планета Земля

Репутация: 16
Всего: 38



Люди, я тупею со страшной скоростью  smile 
Есть такая задача: необходимо создать dll-файл, в котором присутствуют функции запросов по http в потоках. Т.е. программа подключает dll, вызывает необходимую функцию http (get или post). Dll в свою очередь создает поток, в котором создает IdHTTP и выполняет необходимый запрос. После выполнения запроса возвращает результат. Все это необходимо для того, чтобы я мог из программы одновременно создать 10 http-запросов, которые выполнялись бы параллельно. Вот тут у меня тупик (наверное сказывается пара дней без сна). Вот что имею:

Модуль потока:
Код

unit uThread;

interface

uses
  Classes,
  SysUtils,
  IdHTTP,
  IdCookieManager;

type
  THTTPThread = class(TThread)
  private
    { Private declarations }
    FUrl: string;
    FParams: TStrings;
    FResult: string;
    FCommand: string;
    FResultCode: Cardinal;
    FHTTP: TIdHTTP;
    FCookie: TIdCookieManager;
    procedure Get;
    procedure PostStrings;
  protected
    procedure Execute; override;
  end;

implementation

uses
  uConsts;

{ HTTPThread }

procedure THTTPThread.Execute;
begin
  FResult := '';
  FResultCode := ErrNo;
  FHTTP := TIdHTTP.Create(nil);
  FCookie := TIdCookieManager.Create(nil);
  try
    FHTTP.CookieManager := FCookie;
    FCommand := LowerCase(FCommand);
    if FCommand = 'get' then Get else
    if FCommand = 'post' then PostStrings else
    FResultCode := ErrCommand;
  finally
    FreeAndNil(FCookie);
    FreeAndNil(FHTTP);
  end;
end;

procedure THTTPThread.Get;
begin
  FResult := '';
  FResultCode := ErrGet;
  if not Assigned(FHTTP) then
    begin
      FResultCode := ErrInit;
      Exit;
    end;
  try
    FResult := FHTTP.Get(FUrl);
    if FResult = ''
      then FResultCode := ErrTimeout
      else FResultCode := ErrNo;
  except
    FResultCode := ErrConnect;
  end;
end;

procedure THTTPThread.PostStrings;
begin
  FResult := '';
  FResultCode := ErrPost;
  if not Assigned(FHTTP) then
    begin
      FResultCode := ErrInit;
      Exit;
    end;
  try
    FResult := FHTTP.Post(FUrl, FParams);
    if FResult = ''
      then FResultCode := ErrTimeout
      else FResultCode := ErrNo;
  except
    FResultCode := ErrConnect;
  end;
end;

end.


Модуль Dll:
Код

unit uInet;

interface

uses
  Classes,
  uConsts;

procedure Init(Timeout: Cardinal);
function GetError(ACode: Cardinal): string;
function Get(const AUrl: string; out AReq: string): Cardinal;
function PostStrings(const AUrl: string; AParams: TStringList; out AReq: string): Integer;

var
  FInit: Boolean;
  FTimeout: Cardinal;

implementation

procedure Init(Timeout: Cardinal);
begin
  FTimeout := Timeout;
  FInit := True;
end;  

function GetError(ACode: Cardinal): string;
begin
  case ACode of
    ErrNo:          Result := StrErrNo;
    ErrConnect:     Result := StrErrConnect;
    ErrCommand:     Result := StrErrCommand;
    ErrInit:        Result := StrErrInit;
    ErrTimeout:     Result := StrErrTimeout;
    ErrInitModule:  Result := StrErrInitModule;
    ErrGet:         Result := StrErrGet;
    ErrPost:        Result := StrErrPost;
  else Result := StrErrNotFound;
  end;
end;

function Get(const AUrl: string; out AReq: string): Cardinal;
begin
  if not FInit then
    begin
      Result := ErrInitModule;
      Exit;
    end;
  Result := 0;
  AReq := '';

end;

function PostStrings(const AUrl: string; AParams: TStringList; out AReq: string): Integer;
begin
  if not FInit then
    begin
      Result := ErrInitModule;
      Exit;
    end;
  Result := 0;
  AReq := '';
  
end;  

end.


Я не могу понять, как сделать так, чтобы при каждом вызове функция Get или PostStrings создавался новый поток, но не терялся старый...
Поставьте меня plz на путь истинный... smile 


--------------------
user posted image
PM MAIL WWW Skype   Вверх
Romikgy
Дата 2.2.2007, 10:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 26
Всего: 146



Я бы создал в длл динамический список хенделов потоков 
да и вообще те чет надо придумать с асинхроным приходом ответов с сайтов имхо


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
aktuba
Дата 2.2.2007, 10:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Смышленный
***


Профиль
Группа: Завсегдатай
Сообщений: 1915
Регистрация: 24.4.2006
Где: Планета Земля

Репутация: 16
Всего: 38



Цитата

Я бы создал в длл динамический список хенделов потоков 
да и вообще те чет надо придумать с асинхроным приходом ответов с сайтов имхо 


На счет динамического списка - есть такая мысль, вот только как правильно реализовать?
А насчет асинхронного - вообще связываться не хочу, если честно....


--------------------
user posted image
PM MAIL WWW Skype   Вверх
Romikgy
Дата 2.2.2007, 10:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 26
Всего: 146



Цитата(aktuba @  2.2.2007,  09:36 Найти цитируемый пост)
На счет динамического списка - есть такая мысль, вот только как правильно реализовать?

при запуске потока , первые строки заносят в глобальный список потоков, хендл себя,
при окончании потока , свой хендл вычеркивает из списка smile
Цитата(aktuba @  2.2.2007,  09:36 Найти цитируемый пост)
А насчет асинхронного - вообще связываться не хочу, если честно.... 

хы , а терь представь у тя 2 сайта, 1 грузиться быстро , второй медленно,
в длл запускаются 2 потока, (кса я так и не понял с ответом из длл)
как я понимаю управления после запуска потоков передается основной проге( потоку) 
и с 1 сайта уже скачалось и ответ попал в ответый стринг , а со второго еще качается,
как ты думаешь когда инфа закачается со второго сайта, кому она ответ передаст?


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
aktuba
Дата 2.2.2007, 10:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Смышленный
***


Профиль
Группа: Завсегдатай
Сообщений: 1915
Регистрация: 24.4.2006
Где: Планета Земля

Репутация: 16
Всего: 38



Цитата

Цитата(aktuba @  2.2.2007,  09:36 Найти цитируемый пост)
На счет динамического списка - есть такая мысль, вот только как правильно реализовать?

при запуске потока , первые строки заносят в глобальный список потоков, хендл себя,
при окончании потока , свой хендл вычеркивает из списка smile
Цитата(aktuba @  2.2.2007,  09:36 Найти цитируемый пост)
А насчет асинхронного - вообще связываться не хочу, если честно.... 

хы , а терь представь у тя 2 сайта, 1 грузиться быстро , второй медленно,
в длл запускаются 2 потока, (кса я так и не понял с ответом из длл)
как я понимаю управления после запуска потоков передается основной проге( потоку) 
и с 1 сайта уже скачалось и ответ попал в ответый стринг , а со второго еще качается,
как ты думаешь когда инфа закачается со второго сайта, кому она ответ передаст? 


Вот и я про то... Есть такая идея: программа вызывает функцию передавая свой хендл. в длл в TList добавляется новый поток со всеми данными. когда поток отработал, посылается сообщение программе. программа получив сообщение вызывает еще одну функцию, которая и возвращает результат. Вроде так...

Можно как-то проще сделать?


--------------------
user posted image
PM MAIL WWW Skype   Вверх
Romikgy
Дата 2.2.2007, 11:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 26
Всего: 146



Цитата(aktuba @  2.2.2007,  09:51 Найти цитируемый пост)
программа вызывает функцию передавая свой хендл

зачем это ?
Цитата(aktuba @  2.2.2007,  09:51 Найти цитируемый пост)
Можно как-то проще сделать? 

для твоего случая имхо ни как


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
aktuba
Дата 2.2.2007, 11:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Смышленный
***


Профиль
Группа: Завсегдатай
Сообщений: 1915
Регистрация: 24.4.2006
Где: Планета Земля

Репутация: 16
Всего: 38



Цитата

зачем это ?


Как это зачем? Мне же надо сообщить программе что запрос обработан. Значит надо знать, куда слать сообщение...


--------------------
user posted image
PM MAIL WWW Skype   Вверх
CatATonik
Дата 2.2.2007, 13:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 95
Регистрация: 12.1.2007
Где: Москва

Репутация: 6
Всего: 8



Может лучше потоку передавать указатель на CallBack функцию? Типа поток отработал, вызвал функцию передал ей текст ответа и код ошибки.
PM MAIL   Вверх
MetalFan
Дата 3.2.2007, 15:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 62
Всего: 128



тоже думал над подобно "проблемой")
значит какие мысли)
объекты/процедуры:
1) вызывающая программа(App), 
* список, в котором будут "объекты-отправители-запросов" (THttpRequests
* сам класс "отправитель", THttpRequest
* Callback процедура вида SendThreadCallbackEnd( AppContext: dword; ResultSize: dword);


2) библиотека (Lib), 
* "поток-непосредственный отправитель". например TDllSendThread
* процедура создания "потока-отправителя" вида procedure CreateInitSendThread( AppContext: dword; AData: pointer; ADataSize: dword; var ALibContext: dword );
* процедура инициализации библиотеки. procedure InitLib( AppCallback: TAppCallback); которая в контексте библиотеки сохраняет указатель на callback процедуру из App
* процедура получения данных из DLL, LibGetData( ALibContext: dword; ABuf: pointer; ABufSize: dword;var AReadSize: dword );

что как работает:
* инициализируем Lib
послать данные
1) список создает элемент THttpRequest
 в котором вызывается функция CreateInitSendThread передается указатель-контекст на созданный класс THttpRequest(его надо запомнить в созданном в библиотеке TDllSendThread) и отдаются некоторые данные в DLL(запрос, параметры и проч), возвращается конекст-указатель на класс TDllSendThread в библиотеке. в принципе если он уже запущен, то все. ушли забыли покачто.
2) в TDllSendThread отрабатывает запрос в Execute, "дергает" SendThreadCallbackEnd, в которую передает запомненный AppContext и размер буфера, необходимого для размещения ответа.
3) в  App в SendThreadCallbackEnd приводится к THttpRequest(Pointer(AppContext)) и вызывается PrepareGetData, в которой выделяется необх буфер и вызывается LibGetData...

ну в обчем мысль такая. немножко мурено, но идея вроде правильная) сам реализовывал нечто похожее, только потоки у меня были в самом приложении и вызывали функции из длл... что требовало создания служебных объектовс так называемыми "контекстами" внтури dll.
p.s. конечно же не забываем про потокобезопасность! все критические участки кода (SendThreadCallbackEnd например) в критические секции  smile 

Это сообщение отредактировал(а) MetalFan - 3.2.2007, 15:48


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0496 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.