Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2009.11.29;
Скачать: [xml.tar.bz2];

Вниз

процедура возвращающая параметр заполняемые в потоке   Найти похожие ветки 

 
antonn ©   (2009-09-20 18:12) [0]

Вот, значит :)
Есть некий класс, с методом
SendPOST(const URL:string; response:string)

делает он то, что отправляет хттп POST-запрос на сервер. Хочу выделить для этого доп.поток, но так, чтобы обходиться функцией с приведенными параметрами и не вводить обработчиков вызываемых при отработке потока (метод уже используется в других классах, переписывать много).
Пока только придумал делать бесконечный цикл в котором ждать отклика потока об успешной операции (ну и добавить sleep(1) да application.ProcessMessages). Есть более нормальное решение? :)


 
Ega23 ©   (2009-09-20 18:54) [1]

Бред какой-то. Зачем тебе доп.поток тогда нужен?
И нафига sleep(1) если ProcessMessages уже вызвал?


 
antonn ©   (2009-09-20 19:10) [2]

Потому что без него все приложение подвисает. Часть программы, написаной не мной, и править эту часть я не могу, вызывает метод моего класса, который услужливо должен отдать им результат запроса на сервер.
я же использую другие классы для отправки которые при выполнении и "вешают" все приложение, мой класс их только обслуживает. Хочу вынести часть кода делающего запрос в доп. поток.

Sleep(1) "визуально разгружает" проц :)


 
Ega23 ©   (2009-09-20 19:39) [3]


> вызывает метод моего класса, который услужливо должен отдать
> им результат запроса на сервер.

Если у тебя в основном потоке стоит ожидание результата - ты хоть апстену убейся, но доп.поток тебя не спасёт. Никак. Хоть 9000 потоков навешивай.


 
antonn ©   (2009-09-20 19:53) [4]

да ну :)
function THTTPClient.SendPostURL(const URL:string; const Data:tmemorystream):boolean;
var PacingCounter:int64;
begin
 result:=false;
 PacingCounter:=GetTickCount;
 FPostResponsed:=-1;
 THTTPPOSTNode.create(0,ProxyHost,ProxyPort,ProxyUser,ProxyPass,url,data);
 while not(application.terminated) do begin
   if(FPostResponsed>-1) then begin
     result:=true;
     //комплит
     exit;
   end;
   if (GetTickCount-PacingCounter>10000) then begin
 
      break;
   end;
   sleep(1);
   application.ProcessMessages;
 end;
end;

THTTPPOSTNode - класс доп.потока, FPostResponsed - флаг меняемый когда поток закончит работу (после окончания он уведомляет об этом родителя).
Разумеется с таким подходом нельзя подряд быстро вызывать SendPostURL, флаг то один, но мне это не нужно. Форма и контролы на ней живут обычной жизнью, и ничего не напоминает зависания. Просто мне сам способ такой кажется костыльным :)


 
Медвежонок Пятачок ©   (2009-09-20 20:03) [5]

зачем тебе поток и зачем тебе его ожидание, если и без потока и без ожидания все будет точно так же как и с потоком и с ожиданием?


 
antonn ©   (2009-09-20 20:43) [6]


> Медвежонок Пятачок ©   (20.09.09 20:03) [5]
>
> зачем тебе поток и зачем тебе его ожидание, если и без потока
> и без ожидания все будет точно так же как и с потоком и
> с ожиданием?

->

> да ну :)


с потоком форма не "залипает", можно прикрутить человеческую анимацию этого процесса


 
Медвежонок Пятачок ©   (2009-09-20 20:47) [7]

для этих случаев есть TidAntiFreeze


 
antonn ©   (2009-09-20 20:50) [8]

Инди - это такие маленькие офисные игрушки, да?


 
antonn ©   (2009-09-20 21:03) [9]

в общем оторвитесь от нутрей потока и что он там отправляет, хочу более универсальное решение :)

По другому распишу. Допустим есть метод класса:
function TTG.Post(url:string; var st:Tstrings):boolean;
begin
   sleeeep(150000);
   //какое то долговыполняемое действие.
   st.add("ok");
end;


У экземпляров этого класса вызывается этот метод, и он вешает программу. Но я не могу поправить код, который вызывает мой метод, они его запускают и после отработки получают результат в передаваемый TStrings.
Мало того, что на время отработки метода приложение подвисает, так еще и вызов подряд этого метода у нескольких экземпляров класса займет немало времени (относительно многопоточности) и, опять же, подвесит форму приложения.
Отсюда и родился тот костыль из [4], там создается поток которому передаются нужные параметры, он выполняет напряжную работу и после окончания передает результат моему классу. Нужно было решение которое позволит функции "подождать" пока поток все сделает и не дать всему приложению зависнуть в ожидании.


 
Юрий Зотов ©   (2009-09-20 22:14) [10]

> У экземпляров этого класса вызывается этот метод, и он вешает
< программу. Но я не могу поправить код, который вызывает мой метод,

А переопределмить? override.


 
antonn ©   (2009-09-20 22:56) [11]

тоже не могу, это "не моя территория", так же как попросить переделать ответственного :)

мне хочется узнать:

> решение которое позволит функции "подождать" пока поток
> все сделает и не дать всему приложению зависнуть в ожидании.
>

Есть ли такое? т.е. кусок внутри процедуры я выношу в поток только для одной вещи - чтобы оно не вешало основной поток приложения и не мешало выполнению других функций (ну хотя бы отрисовке формы).


 
Медвежонок Пятачок ©   (2009-09-20 23:26) [12]

мне хочется узнать:

> решение которое позволит функции "подождать" пока поток
> все сделает и не дать всему приложению зависнуть в ожидании.
>

для этих случаев есть TidAntiFreeze


 
Achpile ©   (2009-09-20 23:29) [13]

вообще поток создается функцией CreateThread... Туда передаешь процедуру, а возвращается handle твоего нового потока


 
qwer_qwer   (2009-09-20 23:57) [14]


> Есть ли такое? т.е. кусок внутри процедуры я выношу в поток
> только для одной вещи - чтобы оно не вешало основной поток
> приложения и не мешало выполнению других функций (ну хотя
> бы отрисовке формы).


В чём проблема? - Вынеси код с действиями после получения ответа в отдельную процедуру и выполняй после завершения доп. потока.
Ждать вообще ничего не придётся.


 
antonn ©   (2009-09-21 01:06) [15]


> Ждать вообще ничего не придётся.

еще раз... :(

есть какой то код (чужой), работает примерно так:
st:=Tstringlist.Create;
 try
   //что то делает
   FTG.Post("ya.ru",st);
   //еще что то делает
 finally
   st.free;
 end;

вызывается метод экземпляра моего класса(FTG:TTG из [9]), вызвал - передал параметры, получил обратно - попер дальше. Выше (в [9]) примерный код внутри моего метода (он просто напряжный и долгий, для наглядности там стоит sleep()). При его вызове "как сейчас" форма зависнет намертво (специально для Медвежонков-Пяточков скажу, что TidAntiFreeze не помогает, странно, да? :)).
Если я создам TThread и перенесу в него напряжные расчеты и крикну ему "resume!" то вероятно после этого код в "родительском" потоке "пойдет дальше" (где то я уже ловился на этом и создавал тут тему, когда по невнимательности разрушал класс до того, как поток вернет результат ). А мне нужно в основном потоке "подождать" выполнения кода в доппотоке (их может быть несколько) и не повесить форму, и вернуть результат в передаваемом параметре метода (тут - в var st:Tstrings).

Может я не вижу очевидного, не могли бы набросать простой скелет такой конструкции?


 
Германн ©   (2009-09-21 01:45) [16]


> Может я не вижу очевидного

Мне кажется, что не видишь.
При таком чужом коде я не вижу способа перенести хоть что-то в другой поток для избавления основного потока от зависания.
P.S. Единственное нормальное решение тут указано в Юрий Зотов ©   (20.09.09 22:14) [10].


 
Германн ©   (2009-09-21 02:01) [17]


> Если я создам TThread и перенесу в него напряжные расчеты
> и крикну ему "resume!" то вероятно после этого код в "родительском"
> потоке "пойдет дальше" (где то я уже ловился на этом и создавал
> тут тему, когда по невнимательности разрушал класс до того,
>  как поток вернет результат ).

Ну вот тут тот самый случай, имхо. Ты перенесёшь в доппоток "напряжёнку" и выйдешь из твоего метода  FTG.Post. Сразу после этого чужой код "ещё что-то сделает" и уничтожит экземпляр Tstringlist.


 
DVM ©   (2009-09-21 08:25) [18]


> antonn ©   (21.09.09 01:06) [15]

Ты очевидно хочешь странного, по крайней мере это странно выглядит с твоих слов. Чтоб интерфейс не подвисал, ты выносишь долгие вычисления в доп поток, но потом хочешь ждать завершения этого потока, тем самым ожидание завершения потока заморозят тебе интерфейс.

Чтобы не подвисал интерфейс надо:
1) Создать доп поток, запустить там долгие вычисления.
2) В основном потоке создать цикл (!) ожидающий окончания работы доп потока (метод проверки придумай сам) и вызывающий в этом цикле Application.ProcessMessages периодически. Еще лучше перед запуском потока погасить все прочие контролы, а то поток еще раз запустят того гляди.

А вообще это странно - либо синхронная либо асинхронная работа, мешать одно с другим имхо плохо.


 
Медвежонок Пятачок ©   (2009-09-21 09:07) [19]

1) Создать доп поток, запустить там долгие вычисления.
2) В основном потоке создать цикл (!)


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

либо вообще не трогать потоки, а использовать антифириз.


 
Сергей М. ©   (2009-09-21 09:22) [20]

TMyThread = class(TThread)
..
 FURL: String;
 FResponse: TStrings;
..
 property Response: TStrings read FResponse;
..
end;
..

procedure TMyThread.Exceute;
begin
..
 FResponse := SengRequest(FURL); //make blocking call
..
end;
..
var
 hThread: THandle;
 Msg: TMsg;
..
MyThread := TMyThread.Create(URL);
try
 hThread := MyThread.Handle;
 while not Application.Terminated do
   case MsgWaitForMultilpeObjects(1, hThread, False, INFINITE, QS_ALLINPUT) of
   WAIT_OBJECT_0:
     begin
        if Assigned(MyThread.FatalException) then
           raise MyThread.FatalException;
        ShowMessage(MyThread.Response.Text);
        break;
     end;
   WAIT_OBJECT_0 + 1:
      begin
         PeekMessage(Msg, 0, 0, 0, PM_REMOVE);
         Application.ProcessMessage(Msg);          
      end;
   end;
finally
 MyThread.Free;
end;


 
Anatoly Podgoretsky ©   (2009-09-21 11:57) [21]

> Медвежонок Пятачок  (21.09.2009 09:07:19)  [19]

Лучше не использовать антифириз


 
Сергей М. ©   (2009-09-21 12:04) [22]


> Лучше не использовать антифириз


Угу.
В очумелых ручках индейский антифриз превращается в букет граблей.

Да и лучше не использовать индейцев вообще. Без особой на то нужды, разумеется.


 
Медвежонок Пятачок ©   (2009-09-21 12:08) [23]

Лучше не использовать антифириз

Я и не говорил, что лучше.
Он был предложен в связи с тем, что поток ему хочется, а рефакторить код под поток не хочется


 
antonn ©   (2009-09-21 12:13) [24]


> Чтобы не подвисал интерфейс надо:
> 1) Создать доп поток, запустить там долгие вычисления.
> 2) В основном потоке создать цикл (!) ожидающий окончания
> работы доп потока (метод проверки придумай сам) и вызывающий
> в этом цикле Application.ProcessMessages периодически. Еще
> лучше перед запуском потока погасить все прочие контролы,
>  а то поток еще раз запустят того гляди.

это я сделал в [4], мне показалось костылем, вот и создал тему... Оно работает, интерфейс не морозится, на любых "трудноперевариваемых" данных и при нескольких потоках, но кажется костылем :)


 
antonn ©   (2009-09-21 12:13) [25]


> а рефакторить код под поток не хочется

не можется


 
DVM ©   (2009-09-21 21:40) [26]


> Медвежонок Пятачок ©   (21.09.09 09:07) [19]


> вот только не надо этого дибилизма.

Не надо мне тут рассказвать про дибилизм. Это единственный способ добиться в точности того, что он хочет. Антифриз это из другой оперы совсем и применять его надо совсем в другом случае.


 
DVM ©   (2009-09-21 21:44) [27]


> antonn ©   (21.09.09 12:13) [24]


> это я сделал в [4], мне показалось костылем, вот и создал
> тему...

А это и есть костыль. По хорошему так не стоит делать.


 
dima_q   (2009-10-14 11:32) [28]

Если тема еще актуальна, то лучшее решение для твоего вопроса здесь: http://www.delphikingdom.ru/asp/viewitem.asp?catalogid=1355



Страницы: 1 вся ветка

Форум: "Начинающим";
Текущий архив: 2009.11.29;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.53 MB
Время: 0.217 c
2-1255354491
AlexDan
2009-10-12 17:34
2009.11.29
form2.memoN в rave reports..


1-1226938293
burbuluc
2008-11-17 19:11
2009.11.29
Как выйти из ступора?


2-1255588723
Маркабес
2009-10-15 10:38
2009.11.29
Как составить SQL запрос в жоские условия ?


11-1193486478
D[u]fa
2007-10-27 16:01
2009.11.29
KOL_MCK for Delpi 2007 Turbo worked


2-1255507653
123123
2009-10-14 12:07
2009.11.29
отключить сочетание клавиш





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский