Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

работа с потоками


Страницы:   1 2 3

Ekate ©   (2007-08-03 11:32:00) 

Здравствуйте,уважаемые эксперты!
Снова обращаюсь за вашей помощью.
Я вызываю дочерний поток (далее поток_2) из потока(поток_1),который опять же является дочерним к основной программе.
Поток_2 имеет параметр,значение которого передается потоком_1.
Т.е. конструктор потока_2 выглядит следующим образом:

constructor TBr.create(param: string; createsuspended: boolean);
begin
 inherited create(true);
 par := param;
 if not createsuspended then
 resume
end;


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

Код перезапуска потока_2

//if process is runnig then terminate it
       if (br<>nil) then
       begin
           br.Terminate;
           br.WaitFor;
           br := nil;
       end;

       //and run it again with certain parameters
       br:=TBr.Create(anotherParam,true);
       br.Resume;
       br.Priority:=tpnormal;
       


Поток_2 представляет собой сканирование URL активного окна браузера и выполняет работу с тектовым файлом.

Основные процедуры потока_2

function GetUrl:string;
var Winds: IShellWindows;
   IEWB: IWebBrowser2;
   i: integer;
   Doc: IHtmlDocument2;
begin
 Winds:=CoShellWindows.Create;
 for i:=0 to Winds.Count-1 do
 if (Winds.Item(i) as IWEbBrowser2).Document<>nil then
 begin
   IEWB:=Winds.Item(i) as IWEbBrowser2;
   if IEWB.Document.QueryInterface(IhtmlDocument2, Doc)= S_OK
   then Result:=Doc.url;
 end;
end;

procedure TBr.Execute;
var
 f:textFile;
 s:string;
begin
CoInitialize(nil);
while not Terminated do begin
   s:=GetURL;
   if IfExists(param+'@'+s)=false then  // if record doesn't exist then append it to the file
   begin
     assignFile(f,'toy.txt');
     append(f);
     writeln(f,param+'@'+s);
     CloseFile(F);
   end ;

end;
 CoUnInitialize;
 exit;
end;


Собственно вопрос:
При работе приложения выскакивает следующая ошибка:
Project raised exception class EOleException with message 'Unspecified error'.

Ругается на строку

if (Winds.Item(i) as IWEbBrowser2).Document<>nil then...
в функции GetUrl

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

Подскажите,в чем может быть ошибка.

Всего наилучшего,
Ekate


cerber   (2007-08-08 23:27:00) [1]

ставь снифер на 80 порт и не мешай жить ИЕ.


Сергей М.   (2007-08-08 10:45:00) [2]


> Ekate ©   (08.08.07 10:37) [46]


Ты бы обрисовала идею в целом.

Я так понял, что твоя программа призвана осуществлять некие "фискальные" функции, контролируя и протоколируя ссылки на ресурсы, посещенные юзером ..


Сергей М.   (2007-08-08 10:41:00) [3]


> дело в том, что пользователь может посещать различные web
> ресурсы


Опять непонятно ..

Зачем же ты запускаешь браузеры программно в потоке 1, если юзер в состоянии сам "ручками" запустить браузер и осуществлять навигацию интерактивно ?


Ekate   (2007-08-08 10:37:00) [4]


> Что ж это за сканирование такое, что оно может ощутимо блокировать
> работу потока ?

дело в том, что пользователь может посещать различные web ресурсы, поэтому данное сканирование думаю нужно проводить в потоке.


Сергей М.   (2007-08-08 10:32:00) [5]


> сканируем адрес активной страницы


Что ж это за сканирование такое, что оно может ощутимо блокировать работу потока ? И почему его нельзя выполнить прямо в потоке 1 по завершению навигации ?


> формируем строку (состоит из ряда параметров первого потока
> и URL)


Это тоже практически мгновенное действие.
Резона в его выносе в другой доп.поток пока не вижу.


> помещаем данную строку в файл, если ее там нет


А вот это операция явно не мгновенная, ее-то как раз и есть смысл вынести в поток 2, возможно вместе с операцией формирования этой строки.


Ekate   (2007-08-08 10:25:00) [6]

все просто, сканируем адрес активной страницы, формируем строку (состоит из ряда параметров первого потока и URL), помещаем данную строку в файл, если ее там нет.И так делаем до тех пор, пока один из параметров первого потока не изменится.


Сергей М.   (2007-08-08 10:20:00) [7]


> При запуске браузера включаем другой поток(поток2) (дабы
> не блокировать выполнение первого), который выполняет ряд
> действий с браузером


Что это за "действия" ?

Судя по твоему коду, все эти "действия" вполне могут быть выполнены и в потоке 1, практически никак не влияя на время его реакции на ожидаемое им событие.


Ekate   (2007-08-08 10:16:00) [8]

Суть в следующем, выполняется поток (поток1), который ожидает определенного события.При его наступлении запускается браузер с определенной страницей (в зависимости от события).При запуске браузера включаем другой поток(поток2) (дабы не блокировать выполнение первого), который выполняет ряд действий с браузером.При получении нового события первым потоком загружается новая страница и перезапускается поток 2 с новыми параметрами.

> Да нафих к нему подключаться-то ?

Согласна, можно создавать объект браузера сразу в дочернем потоке (поток 2), и передавать первоначальную адресную строку в качестве параметра.


Сергей М.   (2007-08-08 10:04:00) [9]


> Потому что подключение к уже запущенному браузеру ведется
> из другого потока


Да нафих к нему подключаться-то ? Ты ведь и так уже к нему подключилась, создав объект TInternetExplorer, так зачем же после вызова навиг.метода от него отключаться, если прямо здесь же можно получить результат этой навигации ?


Сергей М.   (2007-08-08 10:02:00) [10]

Я тоже так и не понял, к чему здесь доп.потоки.

Navgiate работает асинхронно. Можно прямо в основном потоке запустить нужное кол-во браузеров, передав им для загрузки нужные URL и установив единый обработчик OnDocumentComplete для всех экз-ров IE. Тогда браузеры последовательно отрапортуют о результатах загрузки вызовами этого обработчика. Можно сделать тоже самое и в одном-единственном доп.потоке, но зачем плодить другие "подключающиеся" доп.потоки - вот это совершенно непонятно.


Ekate   (2007-08-08 09:58:00) [11]


> 1) зачем, в случае использования последней версии GetUrl
> [36] подключаться к браузеру?
> 2) Зачем такую "легкую" функцию (GetUrl [36]) выносить в
> отдельный поток? ))



> К чему эти извраты с поиском окна адресной строки

Потому что подключение к уже запущенному браузеру ведется из другого потока.Я этим потоком сканирую посещенные страницы и выполняю ряд действий.


MetalFan   (2007-08-08 09:49:00) [12]


> подключаюсь к браузеру и запускаю дочерний поток.Функцию
> GetUrl пришлось изменить.

1) зачем, в случае использования последней версии GetUrl [36] подключаться к браузеру?
2) Зачем такую "легкую" функцию (GetUrl [36]) выносить в отдельный поток? ))


Сергей М.   (2007-08-08 09:48:00) [13]


> Ekate ©   (08.08.07 09:36) [36]


Не понял ..

К чему эти извраты с поиском окна адресной строки, когда все тоже самое с успехом и изящно делается обращением к св-ву IHTMLDocument2.URL ?

Можно даже еще проще сделать - перед вызовом метода Navigate установить обработчик события OnDocumentComplete, тогда браузер сообщит о завершении загрузки документа вызовом этого обработчика, передав последним параметром готовуюстроку с URL этого документа.


Ekate   (2007-08-08 09:36:00) [14]


> сорри конечно, а я что льстить должен???

Конечно нет,не должен, просто нельзя так категорично..."бредовый код". Все мы учимся и спотыкаемся на ошибках. Не хотела обидеть


> Сергей М. ©

Спасибо большое,разобралась, код "починила". Теперь работает.
В основном потоке создаю объект IE и перехожу на нужную страничку, а когда Busy становится false подключаюсь к браузеру и запускаю дочерний поток.Функцию GetUrl пришлось изменить.
Выглядит она следующим образом:

function GetUrl:string;
var
 wh,al:hwnd;
 Buffer : array[0..255] of Char;
begin
  try
 wh:=findwindow('ieframe', nil);
 if wh>0 then
 begin
   al := FindWindowEx(wh, 0, 'WorkerW', nil);
   if al>0 then
   begin
     al := FindWindowEx(al, 0, 'ReBarWindow32', nil);
     if al > 0 then
     begin
       al := FindWindowEx(al, 0,'Address Band Root', nil);
       if al > 0 then
       begin
         al:=FindWindowEx(al,0,'ComboBoxEx32', nil);
         if al>0 then
         begin
         SendMessage(al, WM_GETTEXT, 255, integer(@Buffer));
         result:=Buffer;
       end; end;
     end;
   end;
 end;
 except
on e: EOleException do
   showmessage(intToStr(e.ErrorCode));
end;
end;


Еще разспасибо всем,принимавшим участие в обсуждении.
Всего наилучшего,
Ekate


MetalFan   (2007-08-07 17:00:00) [15]


> Данная фраза относилась (может и незаслуженно) к MetalFun,
>  поскольку человек  очень категорично отреагировал (может
> и по поводу, конечно), но после его нелестных высказываний
> ничего не последовало...

сорри конечно, а я что льстить должен???
я указал бросившиеся в глаза ошибки...
а отлаживать приведенный код...
разве что сделаешь и выложишь тестовый проект)


Сергей М.   (2007-08-07 13:25:00) [16]


> Ekate ©   (07.08.07 13:18) [32]


Самое главное чтобы ты поняла [30] - остальное неважно)


Anatoly Podgoretsky   (2007-08-07 13:20:00) [17]

> Ekate  (07.08.2007 10:46:22)  [22]

> Но в данном тестовом приложении выкидывает ошибку Access violation at address 0045D958 in module.Read of address 00000000.

Ну эта ошибка одназначная, какой то объект не создан, значение nil
Надо отладчиком найти.


Ekate   (2007-08-07 13:18:00) [18]


> Ей, видишь ли, нравится фраза "пустые понты")

Данная фраза относилась (может и незаслуженно) к MetalFun, поскольку человек  очень категорично отреагировал (может и по поводу, конечно), но после его нелестных высказываний ничего не последовало...


> А справку она, видишь ли, читать не желает - не царское
> ж дело)

Тут я не согласна.

И вообще,Сергей, спасибо Вам за терпение и отзывчивость.


Сергей М.   (2007-08-07 12:52:00) [19]


> мне нравится...обращаюсь за помощью, а в результате или
> пустые понты или попросту бесконечные вопросы


Ей, видишь ли, нравится фраза "пустые понты")

А справку она, видишь ли, читать не желает - не царское ж дело)


Сергей М.   (2007-08-07 12:45:00) [20]


> Lacmus ©   (07.08.07 12:37) [29]


Да все и так понятно - Автор не анализирует св-во Busy, оттого и напоролась на засаду.

Вообще-то об асинхронностинавигационных вызовов упоминается и в справке и в MSDN)


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо