Закрытие фоновых потоков оконного приложения.
От: Ation Украина ation.pp.ua
Дата: 31.05.10 09:31
Оценка:
Всем привет.

Есть:
оконное приложение, в котором существует множество потоков, которые через Invoke изменяют текст контролов. При закрытии приложения, они останавливаются через установку ManualResetEvent и ожидание завершения через Join.

Проблема:
если в момент ожидания завершения потоков, один из них сначала попробует изменить контрол, то получается dead-lock. Если же забить на Join, то поток может просто вылететь на обращении к disposed объекту.

Как решить? Использовать Abort? Просто перехватывать и умалчивать про исключение?
блог
Re: Закрытие фоновых потоков оконного приложения.
От: shakm Россия  
Дата: 31.05.10 11:03
Оценка:
A>Как решить? Использовать Abort? Просто перехватывать и умалчивать про исключение?

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

— отдельный поток ожидает завершения всех контролируемых потоков, а его завершение я проверяю только при попытке закрытия формы и спрашиваю пользователя — прервать потоки или нет.
— храню пул потоков, и при попытке закрытия проверяю состояние всех потоков пула, и так же, предлагаю пользователю принять решение.

Проверить состояние потока элементарно, варианты: thread.IsAlive или thread.ThreadState
Re[2]: Закрытие фоновых потоков оконного приложения.
От: Ation Украина ation.pp.ua
Дата: 31.05.10 11:25
Оценка:
Здравствуйте, shakm, Вы писали:

A>>Как решить? Использовать Abort? Просто перехватывать и умалчивать про исключение?


S>Ну у меня тоже много потоков, и нужно четко дождаться их завершения.

S>Так вот, я это решаю в различных приложениях одним из этих способов:

S>- отдельный поток ожидает завершения всех контролируемых потоков, а его завершение я проверяю только при попытке закрытия формы и спрашиваю пользователя — прервать потоки или нет.

S>- храню пул потоков, и при попытке закрытия проверяю состояние всех потоков пула, и так же, предлагаю пользователю принять решение.

S>Проверить состояние потока элементарно, варианты: thread.IsAlive или thread.ThreadState


Я понял. Но в том то и проблема, что я не могу ожидать чего либо в главном потоке, в котором быдет выполняться событие закрытия формы. Поэтому ждать один поток, ждать несколько, или проверять состояние потоков и спать, пока все не закроются, я не могу.
блог
Re: Закрытие фоновых потоков оконного приложения.
От: VadimB Россия  
Дата: 31.05.10 11:46
Оценка: 3 (1)
Здравствуйте, Ation, Вы писали:

A>Всем привет.


A>Как решить? Использовать Abort? Просто перехватывать и умалчивать про исключение?


Thread::IsBackground Property
A thread is either a background thread or a foreground thread. Background threads are identical to foreground threads, except that background threads do not prevent a process from terminating. Once all foreground threads belonging to a process have terminated, the common language runtime ends the process. Any remaining background threads are stopped and do not complete.
Re[2]: Закрытие фоновых потоков оконного приложения.
От: Ation Украина ation.pp.ua
Дата: 31.05.10 11:57
Оценка:
Здравствуйте, VadimB, Вы писали:

VB>Здравствуйте, Ation, Вы писали:


A>>Всем привет.


A>>Как решить? Использовать Abort? Просто перехватывать и умалчивать про исключение?


VB>Thread::IsBackground Property

VB>A thread is either a background thread or a foreground thread. Background threads are identical to foreground threads, except that background threads do not prevent a process from terminating. Once all foreground threads belonging to a process have terminated, the common language runtime ends the process. Any remaining background threads are stopped and do not complete.

Спасибо. Проверил, такой вариант не вызывает перечисленных проблем. И похоже не может иметь других побочных проблем.
блог
Re: Закрытие фоновых потоков оконного приложения.
От: shakm Россия  
Дата: 31.05.10 13:11
Оценка: +2
Здравствуйте, Ation, Вы писали:

A> ..... и ожидание завершения через Join.


зачем ждать? ведь как ни крути, ждать того, кто ждет тебя (Invoke) — это по любому дэдлок!

Кроме этого, тебе без разницы, что будет с потоками? или есть разница сбойно ли и тихо ли они завершаться, или завершаться по строгому алгоритмму?
И вот ты пишешь, что боишься сбойного завершения:

A> Если же забить на Join, то поток может просто вылететь на обращении к disposed объекту.


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

тебе приводят в пример:

A> Thread::IsBackground Property ... Any remaining background threads are stopped and do not complete.


Как ты думаешь, "...are stopped and do not complete" — это не тоже ли самое, не приведет ли это к неопределенному поведению, что и Abort, который ты сам предложил вызвать и проглотить исключение?

Т.е., если тебя не устраивет НЕ-нормальное завершение потоков, естественно ты не хочешь дэдлоков, тогда почему Abort бля тебя менее "вкусный", чем "IsBackground = true", котрый приводит к неконтролируемому завершению потоков?

Дело не в фоновости потоков (IsBackground == true), дело в неконтролируемости их завершения, даже пусть бы они у тебя были фоновые.
Я потому и стоплю все свои потоки явно, запуская для этого специальный поток, который заведомо отработает быстро и четко. Да и сами потоки умеют понимать команды форсированного завершения. Я понимаю, что не просто остановить потоки иначе, чем абортом, если тебе не доступны сурсы.
Ты думаешь люди пишут сервера так, на авось оставляя потоки на произзвол судьбы только лишь вытавив им IsBackground = true?
Коненчо, я тоже использую фоновые потоки, но все же слежу за из четким форсированным завершением.
Именно об этом я хотел сказать в своем посте. Извини, видимо неверно и неполно сформулировал свою мысль. Советую следить за тем, как у тебя все завершается, это как минимум приучает к порядку....
Re[2]: Закрытие фоновых потоков оконного приложения.
От: Ation Украина ation.pp.ua
Дата: 31.05.10 16:45
Оценка:
Да, все так )
Проблема с Abort следующая. При большом количестве потоков, если внутри синхронизация доступа идет через мьютекс, возможно получение исключения, если грохнуть поток, захвативший этот самый мьютекс. Делать потоки фоновыми, как оказалось после дополнительного тестирования, тоже вопрос удачи.

Я думаю подойдет такой вариант:
добавить обработчик события Closing, в котором создавать поток, который остановит фоновые, и потом закроет форму. А в самом обработчике говорить, что закрытие надо отменить.

офф: а какие такие сервера пишутся на .Net ?
блог
Re[3]: Закрытие фоновых потоков оконного приложения.
От: shakm Россия  
Дата: 01.06.10 05:59
Оценка:
Здравствуйте, Ation, Вы писали:

A>офф: а какие такие сервера пишутся на .Net ?


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

А вообще, у меня сервис, который выполняет кучу разной работы, по сути является сервером приложений. При чем, сервер сделан в виде системы подключаемых плагинов, с минимальным контрактом. Я на любой или группу копмпьютеров отправляю новую сборку и файл описывающий строки названий класса из этой сборки и метода, котрый надо выполнять и по какому расписанию. Сервер это цепляет и выполняет. И таких плагинов не мало, и группы разных плагинов выполняются в различных доменах, в своих потоках, и за всем этим аккуратно следит сервис, и вовремя и аккуратно их останавливает при останове сервиса или выключение компа.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.