Я получил поток, который просто высылает.. я хотел бы знать, кто уничтожает мой поток и почему.
Это происходит со мной, мой поток уничтожается ОС, но я хотел бы подтвердить это и, если возможно знать, почему это уничтожает его.
Что касается потока, я могу утверждать, что он имеет по крайней мере 40 минут выполнения перед смертью, но он внезапно умирает приблизительно 5 минут.
public void RunWorker()
{
Thread worker = new Thread(delegate()
{
try
{
DoSomethingForALongLongTime();
}
catch(Exception e)
{
//Nothing is never logged :(
LogException(e);
throw e;
}
});
worker.IsBackground = true;
worker.SetApartmentState(System.Threading.ApartmentState.STA);
worker.Start();
}
Править: Обращение к ответам
Думание об этих вещах принесло мне к этому вопросу, кто уничтожает мои потоки??
PS. Это не леди Goldent в гостиной с палкой свечи :)
Различные люди (включая меня, здесь) указывали, что размещение длительно работающего потока в IIS - плохая идея. Ваш поток будет работать внутри "рабочего процесса" IIS. Эти процессы периодически завершаются (перезапускаются) службами IIS, что приводит к захохаю потока.
Я предлагаю попробовать отключить перезапуск рабочих процессов IIS, чтобы посмотреть, имеет ли это значение. Вы можете найти больше информации здесь.
Возможно, процесс завершается. Вот что будет worker.IsBackground = true; предназначен для того, чтобы убить ваш поток при выходе из основного потока.
Вероятно, ваша ветка вызвала исключение. Попробуйте поместить блок try / catch вокруг DoSomethingForALongLongTime
и посмотрите, что он улавливает.
Обновление: Раньше я не замечал, что вы запускали это с веб-сервера. Это может быть очень плохой идеей. В частности, использует ли отдельный поток какую-либо информацию, полученную из HttpContext.Current
? Это будет включать запрос
, ответ
, сеанс
и т. Д., А также любую информацию со страницы.
Это плохо, потому что эти вещи существуют только до тех пор, пока длится запрос. После завершения запроса они становятся недействительными, мягко говоря.
Если вам нужно запустить длительный поток из веб-приложения или веб-службы, вы должны создать простую службу Windows и разместить в ней службу WCF. Затем попросите веб-страницу отправить в службу всю информацию, необходимую для выполнения задачи. Служба может даже использовать MSMQ в качестве транспорта, что гарантирует, что сообщения не будут потеряны, даже если служба будет занята.
Если проверка исключения не показывает ничего полезного, заставьте код потока записывать в файл журнала в ключевых точках. Тогда вы сможете точно увидеть, когда он перестанет работать и, надеюсь, почему.
Простой ответ: «Убийца не оставляет визитной карточки»;)
Надеюсь, это поможет.
Фоновый поток будет работать только до тех пор, пока есть запущенные потоки переднего плана.
Как только все потоки переднего плана закончатся, все еще работающие фоновые потоки будут прерваны.
Ваше изменение показывает ответ:
Это
дворецкийвеб-сервер.
Как именно вы размещаете эти темы? Среда веб-сервера не совсем предназначена для размещения долгоживущих процессов. Фактически, он, вероятно, настроен на остановку сбежавших сайтов, может быть, каждые 40 минут?
Изменить:
Для быстрого исправления ваш лучший шанс - установить worker.IsBackground = false;
, потому что ваш текущая установка true позволяет системе убить родительский поток без ожидания вашего bgw.
С другой стороны, нет смысла использовать BackgroundWorker в приложении ASP.NET, он предназначен для WinForms и WPF. Было бы лучше создать для этого отдельный поток, поскольку вы меняете некоторые свойства потоков. Это не рекомендуется для потока ThreadPool (Bgw).
Я не знаю ответа, но некоторые мысли:
ОБНОВЛЕНИЕ
Вы сказали:
Этот поток создается веб-сервером , который продолжает работать
Если поток выполняется внутри asp.net может случиться так, что поток будет убит, когда рабочий процесс asp.net перезапустится, что он будет делать периодически. Вы можете попробовать отключить повторное использование рабочего процесса и посмотреть, имеет ли это значение.
Вы можете попытаться увеличить значение executionTimeout для configuration \ system.web \ httpRuntime в Интернете. .config (значение по умолчанию 110 секунд в .NET 4.0 и 90 дюймов соответствует http://msdn.microsoft.com/en-us/library/e1f13641.aspx ). Вы можете попробовать изменить его динамически Server.ScriptTimeout = 300 (см. http://www.beansoftware.com/ASP.NET-Tutorials/Long-Operations.aspx ). Если этот параметр не поможет, тогда, я думаю, у вас есть другая проблема, такая как повторное использование потоков из IIS. Как вы можете увидеть, что значение этого параметра по умолчанию намного меньше типичного времени жизни вашего потока. Думаю, у вашей проблемы другой характер, но, разумеется ...
Почему вы устанавливаете состояние квартиры для потока? Какие COM-объекты вы используете в рабочем потоке? У вас есть неуправляемый код, который выполняет большую часть работы, куда вы также можете вставить какой-то код? Я думаю, вам нужно больше информации о SomethingForALongLongTime
, чтобы решить эту проблему.
И еще одно небольшое предложение.Не могли бы вы вставить строку кода после вызова SomethingForALongLongTime ();
, чтобы убедиться, что SomethingForALongLongTime
не закончится без исключения?
ОБНОВЛЕНО: Чтобы быть абсолютно уверенным, что ваш поток будет Чтобы не убивать IIS, вы можете попытаться создать процесс, выполняющий SomethingForALongLongTime ();
вместо использования потоков.
Потенциальный способ получить дополнительную информацию: подключить отладчик и прервать работу при завершении потока. В зависимости от того, как завершается ваш поток, это может не сработать.
sxe et
чтобы разрешить прерывание при выходе из потока .loadby sos mscorsvr
, .loadby sos mscorwks
или .loadby sos clr
должны работать), затем запустите ! Clrstack
(см. ! Help
для других sos commands) Если вы слышите много шума при выходе из других потоков, запишите windbg для продолжения работы после прерывания, если это не тот идентификатор потока, который вас интересует.
Изменить: Если вы считаете, что поток завершается изнутри вашего процесса, вы также можете установить точку останова на TerminateThread
( bp kernel32! TerminateThread
) и ExitThread
( bp kernel32! ExitThread
), чтобы поймать стек убийцы.
Вам следует инструментировать DoSomethingForALongLongTime() большим количеством отладочных логов, чтобы вы могли выяснить, в какой точке код прекращает выполнение. Или подключите отладчик и прерывайте все случайные исключения.
Это может быть одно из различных неустранимых исключений, включая Stack Overflow или Out of Memory. Эти исключения труднее всего отследить.
Как выглядит потребление памяти во время работы этого потока? Можете ли вы использовать профилировщик памяти, чтобы увидеть, не выходит ли он из-под контроля? Можете ли вы добавить логирование во внутренних циклах? Если у вас есть рекурсивный метод, добавьте счетчик и выбрасывайте исключение, если он повторяется невозможное количество раз. Используете ли вы большие объекты, которые могут быть причиной фрагментации кучи больших объектов (вызывает ошибки выхода из памяти, даже если на самом деле вы не вышли).
используйте AsyncTasks для выполнения длительной работы в asp.net
Когда вы вызываете RunWorker (), вы можете добавить ссылку на ваш поток в список. Как только вы обнаружите, что ваш поток умер, вы можете проверить состояние потока, возможно, он покажет, как он умер. Или, возможно, он не умер, он просто ждет какого-то ресурса (например, подключения к базе данных).
List runningThreads = ...
public void RunWorker() {
Thread worker = new Thread(delegate()
..
runningThreads.add(worker);
worker.Start();
}
public void checkThreads() {
for (Thread t : runningThreads) {
Console.WriteLine("ThreadState: {0}", t.ThreadState);
}
}
Попробуйте использовать событие app domain UnhandledException: http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx
это может дать вам некоторую информацию, если вы пропустите некоторые исключения