| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Общие вопросы по .NET и C# > Как(где) создать поток, который работает |
| Автор: Pankon 11.7.2006, 12:28 |
| Как(где) создать поток, который работает после окончания приложения, и его не сьест "сборщик мусора"? |
| Автор: DeadSoul 11.7.2006, 12:33 | ||
1. Зачем? 2. Это невозможно |
| Автор: ivashkanet 11.7.2006, 12:36 |
Поясню: приложение считается работающим, пока работает хотя бы один запущенный им поток То же хотел бы знать? Это вопрос из серии: "Хочу чтобы мое приложение работало после окончания работы" Добавлено @ 12:37 Или вопрос такой: "... потк работающий после закрытия гавной формы приложения"? |
| Автор: Pankon 11.7.2006, 13:31 |
Задача родилась из АСП проекта, в котором, пользователи должены с веб страницы запускать "серверное" приложение(разные экземпляры) и "закрывать" сессию. А запущенные приложения продолжают работу и остановливаются, когда "сделают" всю свою работу. (Серверный application тоже может быть остановлен...) ПС. Может надо виндовс службы организовывать, но я здесь абсолютно не селен |
| Автор: Pankon 11.7.2006, 13:36 |
Что делать то |
| Автор: ivashkanet 11.7.2006, 13:43 | ||
Вообще, это лучше делать силами ASP .Net (ИМХО, ничем от win приложений не отличается, только сразу заточена под многопоточность). А если хочешь под WinForm, то делай одно постоянно работающее приложение, которое будет раздавать потоки всем юзерам (хотя это все уже реализовано в ASP). на то он и серверный, что всегда включен. Остановишь его и все, никто к нему доступа не получит Правда можно сделать отключение при простое, но все равно приложение много не съест ресурсов (в рамках сервера, а не домашнего компа). Так что об этом не стоит заботиться |
| Автор: Pankon 11.7.2006, 14:08 |
| Так все-таки - как (примерный сценарий please)? |
| Автор: ivashkanet 11.7.2006, 14:15 |
| Не понял? ЛЮБАЯ ASP .Net страница ---- приложение работающее на стороне сервера. Которое запускается отдельно для каждого пользователя. В ней можно делать что хочешь (хоть удалить все файлы на компе, хоть выключить его Срочно читать инфу про ASP .Net http://forum.vingrad.ru/index.php?showtopic=34584 Или в Гугл Удачи |
| Автор: Pankon 11.7.2006, 14:38 | ||||
ivashkanet,
|
| Автор: ivashkanet 11.7.2006, 14:42 | ||||
Ясно, не будут же они стопаться не доделав работу Так, вопрос Где должны крутиться приложения? На сервере? Наверное да, ведь
Добавлено @ 14:47 А еще можно, ИМХО, передать работу работающему (всегда, если нет, то запускаем его) приложению. Которое создаст поток. P.S. А еще лучше, подождать людей, которые с этим сталкивались. А то я сейчас насоветую... Хотя, на мой взгляд, все нормуль |
| Автор: Pankon 11.7.2006, 15:03 | ||
| да они долго будут на сервере крутиться и пользователь не дождется подтверждения..., а потом БУХ и timeout их прикончит и сессию закроет, вот тут то юзер и получит "подтверждение"... Угу...
Люди..... . . . . . |
| Автор: ivashkanet 11.7.2006, 15:08 | ||
Я знаю только так
Добавлено @ 15:10 Что ты там такое делать то собрался? На несколько часов??? Не могу себе представить |
| Автор: mr.DUDA 11.7.2006, 15:54 |
| Обычно делается спец. табличка в базе данных, куда складывается последнее состояние юзверя (viewstate или что там может быть в асп.нет), а на сервере работает windows service, который с заданной периодичностью удаляет самые старые записи из этой таблички. Windows service элементарно пишется, в студии шаблон есть. |
| Автор: Pankon 11.7.2006, 16:19 |
| мне нужно именно работающий поток(или экземляр работающего приложения(робота)) на сервере, который делает свою работу и умирает, когда все сделает. Каждый экземпляр такого "серверного робота" получает входные параметры из асп страницы (точнее с пользовательской страницы), но это не вопрос... Вопрос где и как хранить(запускать) такой робот. В сессии - не пойдет.. юзер закрывает броузер и идет спать, а робот должен работать... В СерверАппликатион, говорят тоже может быть остановлен, не зависимо от присутствия серверных переменных(читай запущенных потоков)... Создавать виндовссервисе(несколько - один для каждого юзера) и передовать ему параметры говорят - не возможно Поэтому Как(где) создать поток, который работает, после окончания приложения(сессии)? |
| Автор: mr.DUDA 11.7.2006, 16:55 | ||
А я говорю - возможно. Создай сервис и общайся с ним из ASP.NET-приложения через ремоутинг. Список сессий (объектов) храни в статическом Dictionary в windows service. Добавлено @ 16:56 Неужели пример нужен ? |
| Автор: ivashkanet 11.7.2006, 16:57 | ||||||
Я ж тебе говорил уже:
Этим приложением можно сделать Win-сервис Передавать данные приложению можно так:
|
| Автор: Pankon 11.7.2006, 17:20 | ||||
А несколько..? |
| Автор: ivashkanet 11.7.2006, 17:26 |
Зачем тебе несколько? Одного хватит. Какая разница сколько их, если они могут создать сколько угодно потоков Запущенное, работающее в режиме ожидания. Получило задание --- запустило поток --- ждет. Получило ответ от потока --- обработало ---- опять ждет. |
| Автор: Pankon 11.7.2006, 17:30 |
| Я так и не понял: АСП-приложение, вин-приложение, вин-сервисе (свой вариант) |
| Автор: ivashkanet 11.7.2006, 17:36 |
| Как вижу ситуацию я: АСП-приложение --- пишет в базу (не могу придумать нормальный способ взаимодействия двух разных приложений Win-сервис (зачем доп память на визуализацию жрать). Временами сканирует базу на наличие новой заявки. Есть заявка --- запускаем поток на ее обработку --- ждем новые заявки. Получили ответ от потока --- обрабатываем ---- опять ждет. Вот так. Что непонятно? |
| Автор: mr.DUDA 11.7.2006, 17:57 |
| Сел за пример, и тут простая мысль пришла в голову: а что мешает в рамках ASP.NET-овского приложения стартануть поток, ответственный за задачи "вне страницы" ? Пусть он живёт столько, сколько нужно, и управляет пользовательскими сессиями. З.Ы. ASP.NET - это кстати сам по себе windows service, под которым стартуют потоки (из пула), выводящие каждую страницу. |
| Автор: ivashkanet 11.7.2006, 20:45 | ||
У меня тоже были такие мысли, а потом подумал (с подачи Pankon). А не закроется поток, при закрытии сессии |
| Автор: mr.DUDA 11.7.2006, 23:37 |
Одно другого никак не касается. Есть процесс (aspnet_wp.exe или w3wp.exe), запущенный в нём поток ведёт себя точно так же как в любом другом приложении - 100% проверено. |
| Автор: Pankon 11.7.2006, 23:55 |
| а как же |
| Автор: mr.DUDA 12.7.2006, 08:38 |
Ну остановишь ты IIS, ну и что ? Хочешь, чтобы всё продолжало работать, а смысл ? |
| Автор: Pankon 12.7.2006, 10:32 |
| Хорошо. Тогда.... Ближе к телу, как сказал Мапасан. Есть класс(Klass) с конструктором, который принимает один(..) входной параметер. У класса есть метод, который, в принципе, и делает всю работу, есть свойство, показывающее сосояние класса(обьекта). Как организовать потоки которые запускаются по "вызову" пользователей(с веб-стр) и принимают(см. конструктор) параметер(ы) от пользователя. При этом, поток при окончании работы "освобождает от себя (во сказал И (для админ веб-страницы)была бы возможность во время работы потоков опрашивать их "численность", а так же в каждом потоке иметь возможность "прочитать" то свойства, которое показывает сосояние класса(обьекта). Вот примерно такая задача. Может, конечно, я что-то не правильно описал, но принцип, я думаю, понятен. На вопрос: Неужели примеры нужены ? Отвечаю: А вот и ДА. |
| Автор: mr.DUDA 12.7.2006, 12:11 | ||||||||
| Pankon, лови пример. Создаём веб-сайт с двумя страницами: UserPage.aspx, AdminPage.aspx. На юзерпейдж кидаем текстбокс для имени пользователя (всё по-простому) и Label для вывода информации о состоянии (например, будем туда тайм-аут выводить), на админпейдж - таблицу Table, куда выведем список пользователей и тайм-ауты. Добавляем классы WorkItem.cs и WorkItemManager.cs: первый будет представлять тот самый объект, о котором ты говоришь, с состоянием пользователя и его тайм-аутом. В нём же будет крутиться поток данного пользователя. Второй класс будет хранить коллекцию всех активных WorkItem-ов в виде Dictionary<имя_пользователя,WorkItem>. Список существует в единственном экземпляре, поэтому WorkItemManager сделаем синглетоном. При каждом заходе на страницу UserPage будем проверять, есть ли у WorkItemManager-а WorkItem для данного пользователя (по введённому логину) и будем отодвигать тайм-аут на 30 секунд вперёд. При заходе на страницу AdminPage берём список пользователей и выводим инфу, полученную из WorkItem-а каждого пользователя. UserPage.aspx.cs
AdminPage.aspx.cs
WorkItem.cs
WorkItemManager.cs
Полностью проект - в аттаче: |
| Автор: Pankon 12.7.2006, 14:19 |
mr.DUDA, лови звезду... И "последние" вопросы. Синглетон таботает на уровне приложения Я останавливал сессию - он работает, я очищал аппликатион ..- он работает. Я останавливал - приложение - он не работает Как таковой на синглетон не имеется обьектой ссылки... Тут пробел в моих знаниях: Как сборщик мусора "общается" с синглетонами (Блин никигда не задумывался.) И где почитать? Добавлено @ 14:32 И еще вопрос в догонку. Мой метод, который ваполняет "всю" работу не "спит", а довольно сильно ресурсы тянет. Нужно для него "приоритет" ставить или еще что.(Если каждый такой поток (40 штук и еще если в WorkItem.cs написать static метод, не будет проблем, если к нему будут обращаться разные потоки? |
| Автор: mr.DUDA 12.7.2006, 15:11 | ||||
Синглетон - это понятие из паттернов проектирования. Framework ничего не знает о паттернах. Поэтому смешивать в одну кашу синглетон и сборщик мусора - некрасиво Собственно, сам синглетон WorkItemManager-а существует только для того, чтобы где-то можно было хранить список объектов WorkItem; потоки в моём примере выполняются в рамках объектов WorkItem. То есть, если к примеру даже убрать из проекта класс WorkItemManager, то ничего не мешает создавать "по одному" экземпляры WorkItem-ов и хранить ссылки на них где-нибудь в другой статической переменной класса.
Ресурсы равномерно распределяются между потоками. То есть если сделать 100 потоков - система будет тормозить равномерно между 100 потоками. По идее, нужно как-то ограничивать колическво потоков до 10-20, например используя класс ThreadPool. |
| Автор: Pankon 13.7.2006, 09:59 | ||
|
| Автор: mr.DUDA 13.7.2006, 11:42 | ||
Ну, метод должен быть не static, т.к. сами WorkItem-ы создаются в множестве экземпляров (получить конкретный можно с пом. WorkItemManager.Instance.GetWorkItemForUser(userName)). А чтобы не было многопоточных неприятностей, достаточно в теле метода поставить оператор lock на любой объект. |
| Автор: Pankon 19.7.2006, 14:19 |
| Продолжаем разговор: Расширяем задачу, описанную http://forum.vingrad.ru/index.php?showtopic=103650&st=15# следующим образом: Есть несколько веб-серверов, один из них "центральный". Как, по команде(ам) "центрального" запустить на "дочерних" по одному(2,3,4..) потоку(см. http://forum.vingrad.ru/index.php?showtopic=103650&st=15#), при этом иметь возможность, как и раньше, "опрашивать" численность всех "работающих" на серверах потоках и их состояние (админ старница). (Средствами .НЕТ) ПС. Новый топик, я думаю, нет смысла заводить... |
| Автор: mr.DUDA 19.7.2006, 21:16 |
| Pankon, чем проще программа, тем лучше она работает © Упрощай решение задачи, или лучше продумай условие - возможно, всё проще чем ты думаешь, и не нужны все эти центральные и пр. потоки на сервере... |
| Автор: Pankon 19.7.2006, 23:02 |
| Неполучается... Есть четыре (минимум) сервера, рапределенной работой на которых нужно управлять через WEB-интерфейс... (Всмысле, пользователь то об этом и не догадывается, а только получает информацию, что "процесс идет"... а позже проверяет результат работы(из БД)). Администратор должен иметь "расширенные" возможности, т.е. иметь возможность "наблюдать и управлять" процессами(на 4х серверах), которые запустили пользователи... Реализация для одного сервера практически готова.... Все работает... А вот, как "растянуть" это на на четыре IIS сервера пока что не знаю. |
| Автор: mr.DUDA 20.7.2006, 10:40 |
| Pankon, тогда пускай они (серверы) общаются между собой как обычный клиент-сервер. Самый простой и удобный способ - выставить наружу веб-сервис, управляющий потоками сервера и выдающий информацию о тек. состоянии сервера. |
| Автор: Pankon 20.7.2006, 11:37 |
| Спасибо. Сегодня утром, поразмышляв немного, пришел тоже к выводу, что нужно организовывать Web service на каждом сервере.... Уже пишу Manager для центрального севера |
| Автор: Pankon 8.9.2006, 16:58 | ||
Грабли.... Сервер 2003 прибивает поток через 20 минут работы.... Сервер 2000 работает как часы - часами Однако, что же такое с сервером 2003 ПС. Пробовал менять timeout - результат - тот же |
| Автор: mr.DUDA 8.9.2006, 21:39 | ||
видимо, есть настройки типа Thread Pool в самом IIS под 2003-ю винду... там кстати и worker process по другому называется |
| Автор: Yama 14.12.2006, 12:34 |
| 1. при работе он-лайн приложения у тебя ВСЕГДА работает веб-сервер(IIS, Apache или что-либо другое) 2. Зачем тебе переЦЦа в лоб, если можно с боку подойти? - Делаешь вин-службу или любое(хоть консольное) приложение, которому передаешь необходимые параметры запуска приложения любым удобным для тебя способом, т.е., по сути, юзер из своей сессии передает лишь параметры запуска нужного ему приложения в службу(или другое приложение), которое запускает нужное ему(юзеру), приложение и при этом оно не привязано к веб-серверу и, соответственно, к сессии юзера, т.к. запустила его совершенно другая служба(приложение). |