![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Правильно ли работаю с потоками? [D7, XP]
Lamer6666 © (2011-07-26 23:27:00)Доброго времени суток уважаемые!
Решаю следующую задачу, по таймеру получаю методом 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-27 17:48:00) [41]
> Dennis I. Komarov © (27.07.11 17:42) [42]
какой именно?
Dennis I. Komarov (2011-07-27 17:42:00) [42]А еще был приведен довольно неудачный пример, якобы когда это допустимо...
antonn (2011-07-27 17:40:00) [43]Еще один примерчик: у меня программа строит списки, время от времени их пересчитывая, большие списки. И переодически сбрасывает кеш данных на диск. Если при запуске кеш окажется валидным то он будет загружен и пока будет идти перерасчет узер увидит данные за такое-то время сформированные (он и так вообще-то смотрит только данные кеша, который строится на этих вот больших списках, поэтому при старте программы кеш пустой и юзер смотрит в пустой экран).
Так вот мне глубоко пофиг почему не записался кеш, пофиг что там файл был занят, что было реад_онли, что винчестер сглючил или вообще пути для кеша не существует. Ну получу я код ошибки запрета записи на диск, и чего? юзеру это не нужно, а вполне вероятно он не сделает того о чем я его попрошу на основании этой ошибки (дать доступ на запись). А запишется кеш - ну и замечательно. Нет - переживем.
antonn (2011-07-27 17:34:00) [44]
> причем тут с начала, когда если пишешь код [32] то ССЗБ
а если этот код пишет борланд?
но вернемся к моей просьбе: Герман высказался против пустой секции, я высказался что такое решение омеет право на жизнь в зависимости от ситуации. меня начали переубеждать в обратном, т.е. что пустой секции никогда и ни при каких обстоятельствахбыть не должно. Такая логика? Вот и смеюсь, такие все жутко правильные и педантичные куда бы деться :)
Dennis I. Komarov (2011-07-27 17:31:00) [45]
> antonn © (27.07.11 17:24) [38]
причем тут с начала, когда если пишешь код [32] то ССЗБ
... и при этом задаешь откровенно глупые вопросы. Это как расценивать?
antonn (2011-07-27 17:24:00) [46]
> Dennis I. Komarov © (27.07.11 17:22) [37]
посоветую почитать все с начала
Dennis I. Komarov (2011-07-27 17:22:00) [47]
> просто чтобы уточнить - вот если вот тут вылезет эксепшн
> - тоже в отдельную функцию заворачивать? :)
см. [35]
antonn (2011-07-27 17:12:00) [48]я над ними смеюсь.
жестковато? отнюдь :)
sniknik (2011-07-27 17:09:00) [49]> ага, в одном обработчик исключений есть, а в другом нет. Поэтому вручную все работает, а в фоне нет.
> Песня :)
ты дебил или притворяешься?
sniknik (2011-07-27 17:07:00) [50]> как я и говорил - да или нет
долго учился читать только интересное/подтверждающее себя любимого?
расшифровка ошибки есть, у тебя же с пустым и типа неважным ексептом ее не может быть в принципе. (в данном коде, т.что не надо про winapi с функциями возвращающими... и еже с ними.)
antonn (2011-07-27 17:00:00) [51]
> а то и получится так что ручное работает а авто нет, код
> то разный
ага, в одном обработчик исключений есть, а в другом нет. Поэтому вручную все работает, а в фоне нет.
Песня :)
antonn (2011-07-27 16:59:00) [52]
> а статусом у задачи по обновлению (красный значок с расшифровкой
> ошибки если по нему кликнуть).
как я и говорил - да или нет. А не "я не могу проверить обновление потому что некий 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;
sniknik (2011-07-27 16:55:00) [53]> меня интересует результирующее "да или нет".
а меня, как юзера, интересует почему вдруг не сработало назначенное мной же авто обновление, и можно ли исправить/настроить.
а то и получится так что ручное работает а авто нет, код то разный, и нафиг оно мне нужно тогда? а если покажет (лог/статус/...) то окажется например что файрвол "мудрит"/не настроен. и все решится в пять минут.
> юзеру незачем знать
вместо того чтобы решать за юзера, думай как сделать нормально. а то так до решаешься до принципов коммунизма, это когда "товарищи! сегодня потребности в мясе нет.".
Dennis I. Komarov (2011-07-27 16:52:00) [54]
> antonn © (27.07.11 16:44) [28]
Значит ошибки должны обрабатываться внутри функции, с последующей возможностью узнать о ней если будет интересно, а-ля GetLastError
sniknik (2011-07-27 16:48:00) [55]> код првоерки в фоне наличие обновлений:
антивирусы, те, что юзал показывали... не всплывающими сообщениями конечно, это действительно нафиг не нужно, а статусом у задачи по обновлению (красный значок с расшифровкой ошибки если по нему кликнуть).
т.е. обработка у них есть.
а больше и нету ничего, что требует постоянного обновления, в фоне. ну у меня по крайней мере.
antonn (2011-07-27 16:44:00) [56]
> а может очень даже критично...
может, все может
> Для фоновых процессов надо вести лог, возможно отключаемый,
> но пустая секция except плохо
да лично мне глубоко фиолетово что именно в том коде за ошибка вылезет и на каком моменте, меня интересует результирующее "да или нет". это конкретно про тот пример выше
Dennis I. Komarov (2011-07-27 16:42:00) [57]т.е. на кнопку писать отдельный код для обновления? бред...
а если на кнопке обновляется "по тихому" нет?
а может очень даже критично...
Для фоновых процессов надо вести лог, возможно отключаемый, но пустая секция except плохо
antonn (2011-07-27 16:23:00) [58]
> 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;
юзеру незачем знать почему нельзя достучаться до сервера когда проверка происходит в фоне, он может заниматься другими делами. Конкретную ошибку можно захотеть получить при непосредственном желании юзера или разработчика обновить софт, когда этот юзер будет ожидать действия программы на попытку првоерки обновления (например нажмет кнопку "проверить обновления").
А в фоне - ну не получилось и хрен с ним. Не критично.
Anatoly Podgoretsky (2011-07-27 11:28:00) [59]> Игорь Шевченко (26.07.2011 23:56:03) [3]
Книгу толстую прочитал
sniknik (2011-07-27 09:40:00) [60]> И особенно когда не сильно важно узнать что получилось в результате и не нужна гарантия выполнения - зачем мне знать что там приключилось?
и зачем тогда что-то городить? неважно же. код надо переписать так -
Procedure TKdServerThread.execute;
begin
Try
//результат этого неважен поэтому нафиг он нужен? убираем
Except
//код обработки исключительной ситуации
End;
end;
ну вот так получше. правда стало - а нафига нужен вообще этот execute/поток...