![]() |
Модераторы: Partizan, gambit |
![]() ![]() ![]() |
|
RYB |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 72 Регистрация: 17.1.2007 Репутация: нет Всего: нет |
Здравствуйте.
Такая вот задачка: есть много потоков (1-3000 а может даже и больше из плодится). Каждый делает свою работу - обрабатывание около 100 мегабайт страниц html и запись данных в mysql. Создаю я их через делегаты и соответственно вызываю методом BeginInvoke() (пишу на C# .net 3.5) Ну вот наплодил я 3000 потоков, главная программа всю свою задачу выполнила и хочет закрываться. От того чтоб закрыться прежде времени ее отделяет только Console.ReadLine(). Хоть это и самое ресурсощадящее решение, оно не самое удобное так как понять что все 3000 потоков закрылись тяжело. пробовал сохранять от каждого BeginInvoke() экземпляры класса IAsyncResult, а потом после вызова всех детищь, их в цикле остонавливать через EndInvoke() - но тогда весь процес дико тормозит (не машина тормозит, а процес замедляется и программа работает буд-то в однопоточном режиме) Кто какие способы использовал и может поделится опытом? |
|||
|
||||
Partizan |
|
|||
![]() Let's do some .NET ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 2828 Регистрация: 19.12.2005 Где: Санкт-Петербург Репутация: 18 Всего: 67 |
RYB, при окончании работы потока должно происходить соответствующее событие, на которое вызывающий должен подписаться...
-------------------- СУВ, Partizan. |
|||
|
||||
RYB |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 72 Регистрация: 17.1.2007 Репутация: нет Всего: нет |
Partizan, Спасибо за ответ.
А можно поподробнее: какое именно событие и как подписаться на его поимку? Добавлено через 7 минут и 45 секунд Я кажется понял о чем ты говориш: при вызове BeginInvoke() я указываю CallBack метод, котрый будет вызван по завершению работы потока. Проблема в том что тогда прийдется в так-сказать main() писать бесконечный цикл для проверки условия совпадения числа потоков запущеных и отработавших. Но это будет хавать цп. А есть ли способ завершить главный поток вторичным? |
|||
|
||||
Partizan |
|
|||
![]() Let's do some .NET ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 2828 Регистрация: 19.12.2005 Где: Санкт-Петербург Репутация: 18 Всего: 67 |
пускай по таймеру проверяется число запущенных и остановленных и всё...и цп не будет загружен выполнением бесконечного цикла...
-------------------- СУВ, Partizan. |
|||
|
||||
RYB |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 72 Регистрация: 17.1.2007 Репутация: нет Всего: нет |
Как вариант использовать можно. Даже и без таймера
Спасибо за идею, Partizan. Но всетаки интересно: если еще решение поэлегантнее? |
|||
|
||||
Akina |
|
|||
Советчик ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 20581 Регистрация: 8.4.2004 Где: Зеленоград Репутация: нет Всего: 454 |
Не понимаю... почему нельзя формирование сигнала на завершение работы приложения возложить именно на CallBack-функцию?
В самом начале работы заводим счетчик int counter, запихиваем туда единичку. Инкрементируем, запуская очередной поток. Callback, кроме всего прочего, декрементирует счетчик. Когда все функции основной программы выполнены, вызываем сами эту callback, после чего запускаем просто цикл валяния дурака ( while (counter>0) {Thread.Sleep(1000);} подойдет). Если на момент ручного запуска callback потоков больше нет, счетчик обнулится. Если есть - он обнулится при завершении последнего потока. Вот по этому нулю цикл сдвинется и работа приложения завершится. -------------------- О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума. |
|||
|
||||
Felan |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 284 Регистрация: 2.8.2007 Где: Самара Репутация: нет Всего: 7 |
Я извиняюсь, если что... в .Net не сильно пока еще разбираюсь, но вроде как для таких целей можно использовать спец. объекты синхронизации - семафоры.
Не знаю, можно их использовать под .Net... ЗЫЖ В Делфи точно можно ![]() Это сообщение отредактировал(а) Felan - 13.8.2008, 07:33 -------------------- // Любая сложная система - это темный лес. Каждый в этом лесу протаптывает свои тропинки, по ним и бегает. Лишь изредка, сходя с них, мы находим много интересного, а порою и страшного. |
|||
|
||||
Partizan |
|
|||
![]() Let's do some .NET ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 2828 Регистрация: 19.12.2005 Где: Санкт-Петербург Репутация: 18 Всего: 67 |
Felan, в данном случае не подходит....
-------------------- СУВ, Partizan. |
|||
|
||||
RYB |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 72 Регистрация: 17.1.2007 Репутация: нет Всего: нет |
Почему нельзя, можно и нужно - это я и отметил как решение. Но из опыта: на одну задачю есть масса решений. Поэтому для того чтобы прога работала оптимально и для саморазвития мне интересно какие есть еще варианты. Но видать проще решине врятли найдется. Идея с симофорами (если я ее правильно понял) в данной ситуации не подходит, так как для каждого потока (а их тут куча) необходимо вызвать метод EndInvoke() - Аналог WaitForSingleObject() что и было описано выше. |
|||
|
||||
Akina |
|
|||
Советчик ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 20581 Регистрация: 8.4.2004 Где: Зеленоград Репутация: нет Всего: 454 |
То, что семафоры (а равно и мутексы) не подходят - это очевидно. Их надо опрашивать, а поллинг никогда не относился к красивым решениям, если есть альтернатива.
-------------------- О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума. |
|||
|
||||
Felan |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 284 Регистрация: 2.8.2007 Где: Самара Репутация: нет Всего: 7 |
Возможно я не так понял твой первый пост... Если тебе надо самому завершить все потоки, когда твой основной поток отработал, то да... А если тебе надо дождаться когда они все отработают сами, то нет. Во втором случае логика такая: Ты создаешь семафор. Каждый дополнительный поток при старте его захватывает - у него увеличивается счетчик, а при завершении освобождает - счетчик уменьшается (такова суть семафора). В основном потоке ты просто ждешь пока семафор освободится полностью - его счетчик станет равным 0 (все захватившие его потоки завершились). Функция ожидания не будет кушать такты процессора. Смею утверждать, что семафоры именно для ожидания завершения многих потоков и предназначены... -------------------- // Любая сложная система - это темный лес. Каждый в этом лесу протаптывает свои тропинки, по ним и бегает. Лишь изредка, сходя с них, мы находим много интересного, а порою и страшного. |
|||
|
||||
Partizan |
|
|||
![]() Let's do some .NET ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 2828 Регистрация: 19.12.2005 Где: Санкт-Петербург Репутация: 18 Всего: 67 |
Felan, семафоры предназначены для управления доступом к общим ресурсам. Если надо будет отслеживать завершение каждого отдельного потока, идея с семафорами сразу отпадает.
-------------------- СУВ, Partizan. |
|||
|
||||
RYB |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 72 Регистрация: 17.1.2007 Репутация: нет Всего: нет |
Тогда я не видел нечего похожего в .net. Есть только другие варианты реализации которые несут похожую функциональность: снова тотже CallBack |
|||
|
||||
Felan |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 284 Регистрация: 2.8.2007 Где: Самара Репутация: нет Всего: 7 |
Блин. Точно... они же не в ту сторону считают :( Это сообщение отредактировал(а) Felan - 13.8.2008, 13:26 -------------------- // Любая сложная система - это темный лес. Каждый в этом лесу протаптывает свои тропинки, по ним и бегает. Лишь изредка, сходя с них, мы находим много интересного, а порою и страшного. |
|||
|
||||
Felan |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 284 Регистрация: 2.8.2007 Где: Самара Репутация: нет Всего: 7 |
А если что-нибудь подобное сделать? Вроде не должно тормозить... Понимаю, что сделано не совсем так, как изначально делал автор, но просто для иллюстрации идеи может сойдет?
![]()
-------------------- // Любая сложная система - это темный лес. Каждый в этом лесу протаптывает свои тропинки, по ним и бегает. Лишь изредка, сходя с них, мы находим много интересного, а порою и страшного. |
|||
|
||||
![]() ![]() ![]() |
Прежде чем создать тему, посмотрите сюда: | |
|
Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов. Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :) Так же не забывайте отмечать свой вопрос решенным, если он таковым является :) Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |