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

Вниз

Правильно ли работаю с потоками?   Найти похожие ветки 

 
Lamer6666   (2011-07-26 23:27) [0]

Доброго времени суток уважаемые!
Решаю следующую задачу, по таймеру получаю методом GET информацию. Данную задачу необходимо реализовать в потоке. Делаю так:

Описал тип
type
 TKdServerThread = class(TThread)
 private
 Procedure GetIn;
 protected
   procedure execute; override;
 end;


Процедура исполнения:
Procedure TKdServerThread.execute;
begin
  Synchronize(GetIn);
end;


Выполняю нужный мне код:

Procedure TKdServerThread.GetIn;
begin
   Try
      Form1.Memo1.Lines.Add(IdHTTP99.Get("...."));
   Except
   End;
  Application.ProcessMessages;
end;


Далее по таймеру запускаю потоки:
procedure TForm1.Timer1Timer(Sender: TObject);
 var NewThread: TKdServerThread;
begin
 NewThread:=TKdServerThread.Create(true);
 NewThread.FreeOnTerminate:=true;
 NewThread.Priority:=tpLowest;
 NewThread.Resume;
end;


вопрос:
1. Правильно ли реализовано решение?
2. Что будет если один из потоков повиснет при выполнении метода GET, продолжат ли работу остальные потоки?
3. Как ограничить количество потоков, есть некий параметр показывающий кол-во работающих потоков, или нужно считать кол-во созданных потоков  самому?
Огромное спасибо.


 
antonn ©   (2011-07-26 23:36) [1]

Не правильно, этот код выполнится полностью в главном потоке+накладные расходы на доп.поток.
нужно в Execute получить текст страницы (IdHTTP99.Get("....")) в переменную, а в GetIn() запихнуть в мемо эту переменную.


 
Lamer6666   (2011-07-26 23:49) [2]


> Execute получить текст страницы (IdHTTP99.Get("....")) в
> переменную, а в GetIn() запихнуть в мемо эту переменную.
>

Понял, переделываю.


 
Игорь Шевченко ©   (2011-07-26 23:56) [3]


> Процедура исполнения:
> Procedure TKdServerThread.execute;
> begin
>   Synchronize(GetIn);
> end;


Вот скажите мне, откуда этот код ?


 
Германн ©   (2011-07-27 00:05) [4]


> Вот скажите мне, откуда этот код ?

http://www.delphikingdom.com/asp/viewitem.asp?catalogid=1082
:)


 
Lamer6666   (2011-07-27 00:12) [5]

Статейки нарыл в Интернет под заголовком "Работа с потоками"
:)
А что в нем не так?


 
Германн ©   (2011-07-27 00:17) [6]


> А что в нем не так?

Процедура Execute.


 
Lamer6666   (2011-07-27 00:18) [7]

Имеете ввиду что данные в основной поток надо передавать "Сообщением"?


 
sniknik ©   (2011-07-27 00:21) [8]

> Статейки нарыл в Интернет под заголовком "Работа с потоками"
врешь небось? пруф где?


 
sniknik ©   (2011-07-27 00:23) [9]

> передавать "Сообщением"?
молнией! откуда выводы о не написаном?


 
Lamer6666   (2011-07-27 00:24) [10]


> врешь небось? пруф где?

http://compconnect.ru/2010/10/rabota-s-potokami-v-delphi-7/
:)
Народ дайте ссылку на правильный код, для, так сказать детального изучения.
))


 
sniknik ©   (2011-07-27 00:29) [11]

> http://compconnect.ru/2010/10/rabota-s-potokami-v-delphi-7/
> :)
и правда врешь, т.к. там такого не написано, там все правильно.

> Народ дайте ссылку на правильный код
пожалуйста, вполне правильная ссылка
http://compconnect.ru/2010/10/rabota-s-potokami-v-delphi-7/


 
Lamer6666   (2011-07-27 00:30) [12]

Читаю внимательнее... Спасибо.


 
Lamer6666   (2011-07-27 00:43) [13]

Процедура исполнения:
Procedure TKdServerThread.execute;
begin
  Try
     StrParam1:=IdHTTP99.Get("....");
  Except
  End;
 Application.ProcessMessages;  
 Synchronize(Memo1UpDate);
end;

Выполняю нужный мне код:

Procedure TKdServerThread.Memo1UpDate;
begin
Memo1.....:=StrParam1;
end;

так верно?


 
Lamer6666   (2011-07-27 00:44) [14]

Процедура исполнения:
Procedure TKdServerThread.execute;
begin
 Try
    StrParam1:=IdHTTP99.Get("....");
    Application.ProcessMessages;
 Except
 End;
Synchronize(Memo1UpDate);
end;

Выполняю нужный мне код:

Procedure TKdServerThread.Memo1UpDate;
begin
Memo1.....:=StrParam1;
end;

так верно?


 
Германн ©   (2011-07-27 00:46) [15]


> Lamer6666   (27.07.11 00:30) [12]
>
> Читаю внимательнее... Спасибо.
>

Там всё написано правильно. Только не по


 
Игорь Шевченко ©   (2011-07-27 00:48) [16]

нафиг тебе вообще потоки ?


> http://compconnect.ru/2010/10/rabota-s-potokami-v-delphi-
> 7/


в топку такие примеры.

Хотя бы здесь почитай: http://forum.vingrad.ru/topic-60076.html


 
Lamer6666   (2011-07-27 00:54) [17]

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

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


 
Германн ©   (2011-07-27 00:54) [18]


> так верно?
>

Нет. Не верно.
Во-первых вызов процедуры Application.ProcessMessages в доппотоке не имеет никакого смысла.
Во-вторых пустая часть Except защищенного блока - единица в дневнике!
В-третьих. А чего записывать в Мемо, если Get не получился?

P.S.
В четвертых - не знаю Инди. Так что и не знаю как работает метод TIdHTTP.Get.


 
Lamer6666   (2011-07-27 00:58) [19]


> Нет. Не верно.
> Во-первых вызов процедуры Application.ProcessMessages в
> доппотоке не имеет никакого смысла.
> Во-вторых пустая часть Except защищенного блока - единица
> в дневнике!
> В-третьих. А чего записывать в Мемо, если Get не получился?
>
>

Согласен с Application.ProcessMessages. По поводу Except она будет заполнена, но речь пока не о ней, а о конструкции потока.  Synchronize(Memo1UpDate); будет поднято в Try (не внимательность), а при неудаче сработает  Except .

Procedure TKdServerThread.execute;
begin
Try
   StrParam1:=IdHTTP99.Get("....");
   Synchronize(Memo1UpDate);
Except
   //код обработки исключительной ситуации
End;
end;


 
Lamer6666   (2011-07-27 01:15) [20]

В общем как я понял, процедура execute выполняет все действия вычисления и записывает результат в параметр. Далее процедура Synchronize присваивает значение вышеуказанного параметра объекту главного процесса.


 
Германн ©   (2011-07-27 01:23) [21]


> Lamer6666   (27.07.11 01:15) [20]
>
> В общем как я понял, процедура execute выполняет все действия
> вычисления и записывает результат в параметр. Далее процедура
> Synchronize присваивает значение вышеуказанного параметра
> объекту главного процесса.

Теоретически правильно.


 
antonn ©   (2011-07-27 01:55) [22]


> Во-вторых пустая часть Except защищенного блока - единица
> в дневнике!

Вовсе нет, когда не важно какая ошибка там будет, главное чтобы в потоке не решило появится окошко эксепшена (от этих вот raise я и перешел на синапс, сделал операцию - проверил результат, а не городить эти блоки чтобы гасить эксепшн).
И особенно когда не сильно важно узнать что получилось в результате и не нужна гарантия выполнения - зачем мне знать что там приключилось?


 
Германн ©   (2011-07-27 02:02) [23]


> antonn ©   (27.07.11 01:55) [22]
>
>
> > Во-вторых пустая часть Except защищенного блока - единица
> > в дневнике!
>
> Вовсе нет, когда не важно какая ошибка там будет, главное
> чтобы в потоке не решило появится окошко эксепшена (от этих
> вот raise я и перешел на синапс,

А когда не важно?
И что нам всем переходить на синапс?


 
sniknik ©   (2011-07-27 09:40) [24]

> И особенно когда не сильно важно узнать что получилось в результате и не нужна гарантия выполнения - зачем мне знать что там приключилось?
и зачем тогда что-то городить? неважно же. код надо переписать так -
Procedure TKdServerThread.execute;
begin
 Try
    //результат этого неважен поэтому нафиг он нужен? убираем
 Except
    //код обработки исключительной ситуации
 End;
end;

ну вот так получше. правда стало - а нафига нужен вообще этот execute/поток...


 
Anatoly Podgoretsky ©   (2011-07-27 11:28) [25]

> Игорь Шевченко  (26.07.2011 23:56:03)  [3]

Книгу толстую прочитал


 
antonn ©   (2011-07-27 16:23) [26]


> sniknik ©   (27.07.11 09:40) [24]
>
> Procedure TKdServerThread.execute;
> begin
>  Try
>     //результат этого неважен

результат этого важен. переписать


> Германн ©   (27.07.11 02:02) [23]
>
>
> А когда не важно?

когда это не критично.
код првоерки в фоне наличие обновлений:
Procedure TKdServerThread.execute;
begin
 result_code:=0;
Try
   result_code:=GetUpdateAvailable("...");
Except
End;
 Synchronize(GetIn); //передаю result_code основному потоку
end;


юзеру незачем знать почему нельзя достучаться до сервера когда проверка происходит в фоне, он может заниматься другими делами. Конкретную ошибку можно захотеть получить при непосредственном желании юзера или разработчика обновить софт, когда этот юзер будет ожидать действия программы на попытку првоерки обновления (например нажмет кнопку "проверить обновления").
А в фоне - ну не получилось и хрен с ним. Не критично.


 
Dennis I. Komarov ©   (2011-07-27 16:42) [27]

т.е. на кнопку писать отдельный код для обновления? бред...

а если на кнопке обновляется "по тихому" нет?

а может очень даже критично...

Для фоновых процессов надо вести лог, возможно отключаемый, но пустая секция except плохо


 
antonn ©   (2011-07-27 16:44) [28]


> а может очень даже критично...

может, все может


> Для фоновых процессов надо вести лог, возможно отключаемый,
>  но пустая секция except плохо

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


 
sniknik ©   (2011-07-27 16:48) [29]

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


 
Dennis I. Komarov ©   (2011-07-27 16:52) [30]


> antonn ©   (27.07.11 16:44) [28]

Значит ошибки должны обрабатываться внутри функции, с последующей возможностью узнать о ней если будет интересно, а-ля GetLastError


 
sniknik ©   (2011-07-27 16:55) [31]

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

> юзеру незачем знать
вместо того чтобы решать за юзера, думай как сделать нормально. а то так до решаешься до принципов коммунизма, это когда "товарищи! сегодня потребности в мясе нет.".


 
antonn ©   (2011-07-27 16:59) [32]


> а статусом у задачи по обновлению (красный значок с расшифровкой
> ошибки если по нему кликнуть).

как я и говорил - да или нет. А не "я не могу проверить обновление потому что некий someclass не может вызвать свой метод потому что у него там что то ен получается и вот вам Getlasterror 123456".


> Dennis I. Komarov ©   (27.07.11 16:52) [30]
>
>
> > antonn ©   (27.07.11 16:44) [28]
>
> Значит ошибки должны обрабатываться внутри функции, с последующей
> возможностью узнать о ней если будет интересно, а-ля GetLastError

просто чтобы уточнить - вот если вот тут вылезет эксепшн - тоже в отдельную функцию заворачивать? :) он, кстати, погасится или нет?
А если подобный код есть в каких нибудь "индях" ил других классах? вон в jpeg есть такой момент когда сканлайн прямо указывается с индексом 1, в результате вылезут баги при работе с картинкой в 1 пиксель высотой. Там где мне надо - я перехвачу исключение, но в целом приходится вот так поступать чтобы вообще все приложение не порушилось.
var st:tstrings;
begin

st:=tstringlist.create;
try
 st.loadfromstream();
 st.soft;
 st.strings[512]:="babax!";
finally
 st.free;
end;

end;


 
antonn ©   (2011-07-27 17:00) [33]


> а то и получится так что ручное работает а авто нет, код
> то разный

ага, в одном обработчик исключений есть, а в другом нет. Поэтому вручную все работает, а в фоне нет.
Песня :)


 
sniknik ©   (2011-07-27 17:07) [34]

> как я и говорил - да или нет
долго учился читать только интересное/подтверждающее себя любимого?

расшифровка ошибки есть, у тебя же с пустым и типа неважным ексептом ее не может быть в принципе. (в данном коде, т.что не надо про winapi с функциями возвращающими... и еже с ними.)


 
sniknik ©   (2011-07-27 17:09) [35]

> ага, в одном обработчик исключений есть, а в другом нет. Поэтому вручную все работает, а в фоне нет.
> Песня :)
ты дебил или притворяешься?


 
antonn ©   (2011-07-27 17:12) [36]

я над ними смеюсь.
жестковато? отнюдь :)


 
Dennis I. Komarov ©   (2011-07-27 17:22) [37]


> просто чтобы уточнить - вот если вот тут вылезет эксепшн
> - тоже в отдельную функцию заворачивать? :)

см. [35]


 
antonn ©   (2011-07-27 17:24) [38]


> Dennis I. Komarov ©   (27.07.11 17:22) [37]

посоветую почитать все с начала


 
Dennis I. Komarov ©   (2011-07-27 17:31) [39]


> antonn ©   (27.07.11 17:24) [38]

причем тут с начала, когда если пишешь код [32] то ССЗБ
... и при этом задаешь откровенно глупые вопросы. Это как расценивать?


 
antonn ©   (2011-07-27 17:34) [40]


> причем тут с начала, когда если пишешь код [32] то ССЗБ

а если этот код пишет борланд?

но вернемся к моей просьбе: Герман высказался против пустой секции, я высказался что такое решение омеет право на жизнь в зависимости от ситуации. меня начали переубеждать в обратном, т.е. что пустой секции никогда и ни при каких обстоятельствах быть не должно. Такая логика? Вот и смеюсь, такие все жутко правильные и педантичные куда бы деться :)



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

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

Наверх




Память: 0.56 MB
Время: 0.004 c
6-1245011712
batya15
2009-06-15 00:35
2011.11.20
Работа с http без компонентов


15-1311249647
Scott Storch
2011-07-21 16:00
2011.11.20
запрос на удаление


15-1311712200
Юрий
2011-07-27 00:30
2011.11.20
С днем рождения ! 27 июля 2011 среда


3-1266498498
Den
2010-02-18 16:08
2011.11.20
Буквы Е и Ё. Контекстный поиск


2-1312259634
Grimm
2011-08-02 08:33
2011.11.20
Как правильно написать условие if для StringList.IndexOf ?





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский