Как знать, кто уничтожает мои потоки

Я получил поток, который просто высылает.. я хотел бы знать, кто уничтожает мой поток и почему.

Это происходит со мной, мой поток уничтожается ОС, но я хотел бы подтвердить это и, если возможно знать, почему это уничтожает его.

Что касается потока, я могу утверждать, что он имеет по крайней мере 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 в гостиной с палкой свечи :)

28
задан mcabral 5 May 2010 в 17:03
поделиться

15 ответов

Различные люди (включая меня, здесь) указывали, что размещение длительно работающего потока в IIS - плохая идея. Ваш поток будет работать внутри "рабочего процесса" IIS. Эти процессы периодически завершаются (перезапускаются) службами IIS, что приводит к захохаю потока.

Я предлагаю попробовать отключить перезапуск рабочих процессов IIS, чтобы посмотреть, имеет ли это значение. Вы можете найти больше информации здесь.

20
ответ дан 28 November 2019 в 02:52
поделиться

Возможно, процесс завершается. Вот что будет worker.IsBackground = true; предназначен для того, чтобы убить ваш поток при выходе из основного потока.

3
ответ дан 28 November 2019 в 02:52
поделиться

Вероятно, ваша ветка вызвала исключение. Попробуйте поместить блок try / catch вокруг DoSomethingForALongLongTime и посмотрите, что он улавливает.


Обновление: Раньше я не замечал, что вы запускали это с веб-сервера. Это может быть очень плохой идеей. В частности, использует ли отдельный поток какую-либо информацию, полученную из HttpContext.Current ? Это будет включать запрос , ответ , сеанс и т. Д., А также любую информацию со страницы.

Это плохо, потому что эти вещи существуют только до тех пор, пока длится запрос. После завершения запроса они становятся недействительными, мягко говоря.

Если вам нужно запустить длительный поток из веб-приложения или веб-службы, вы должны создать простую службу Windows и разместить в ней службу WCF. Затем попросите веб-страницу отправить в службу всю информацию, необходимую для выполнения задачи. Служба может даже использовать MSMQ в качестве транспорта, что гарантирует, что сообщения не будут потеряны, даже если служба будет занята.

13
ответ дан 28 November 2019 в 02:52
поделиться

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

2
ответ дан 28 November 2019 в 02:52
поделиться

Простой ответ: «Убийца не оставляет визитной карточки»;)

  • Если ваш поток размещен в IIS, возможно, поток убивается процессом пула приложений, который перезагружается. Сервер может продолжать работать, но процесс, на котором размещен ваш элемент, остановлен до тех пор, пока новый запрос не запустит все снова.
  • Если ваш поток размещен в исполняемом файле, единственный способ его убить - это убить поток самостоятельно, вызвать исключение в потоке или завершить хост-процесс.

Надеюсь, это поможет.

2
ответ дан 28 November 2019 в 02:52
поделиться

Фоновый поток будет работать только до тех пор, пока есть запущенные потоки переднего плана.

Как только все потоки переднего плана закончатся, все еще работающие фоновые потоки будут прерваны.

3
ответ дан 28 November 2019 в 02:52
поделиться

Ваше изменение показывает ответ:

Это дворецкий веб-сервер.

Как именно вы размещаете эти темы? Среда веб-сервера не совсем предназначена для размещения долгоживущих процессов. Фактически, он, вероятно, настроен на остановку сбежавших сайтов, может быть, каждые 40 минут?

Изменить:
Для быстрого исправления ваш лучший шанс - установить worker.IsBackground = false; , потому что ваш текущая установка true позволяет системе убить родительский поток без ожидания вашего bgw.

С другой стороны, нет смысла использовать BackgroundWorker в приложении ASP.NET, он предназначен для WinForms и WPF. Было бы лучше создать для этого отдельный поток, поскольку вы меняете некоторые свойства потоков. Это не рекомендуется для потока ThreadPool (Bgw).

4
ответ дан 28 November 2019 в 02:52
поделиться

Я не знаю ответа, но некоторые мысли:

  • Может ли это вызвать исключение? Вы пробовали использовать try / catch вокруг вызова DoSomethingForALongLongTime ()?
  • Есть ли точки, в которых он завершается нормально? Попробуйте поставить на них какой-нибудь лог.
  • У вас одинаковое поведение в отладчике и вне его? Предоставляет ли окно вывода в отладчике какие-либо подсказки?

ОБНОВЛЕНИЕ

Вы сказали:

Этот поток создается веб-сервером , который продолжает работать

Если поток выполняется внутри asp.net может случиться так, что поток будет убит, когда рабочий процесс asp.net перезапустится, что он будет делать периодически. Вы можете попробовать отключить повторное использование рабочего процесса и посмотреть, имеет ли это значение.

4
ответ дан 28 November 2019 в 02:52
поделиться

Вы можете попытаться увеличить значение 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 (); вместо использования потоков.

2
ответ дан 28 November 2019 в 02:52
поделиться

Потенциальный способ получить дополнительную информацию: подключить отладчик и прервать работу при завершении потока. В зависимости от того, как завершается ваш поток, это может не сработать.

  1. Загрузите Инструменты отладки для Windows , если у вас их еще нет
  2. Запустите windbg.exe, подключитесь к вашему процессу
  3. Взломайте windbg, введите sxe et чтобы разрешить прерывание при выходе из потока
  4. Когда отладчик прерывается, проверьте состояние системы, других потоков и т. д.
  5. Чтобы получить управляемый стек, загрузите sos.dll ( .loadby sos mscorsvr , .loadby sos mscorwks или .loadby sos clr должны работать), затем запустите ! Clrstack (см. ! Help для других sos commands)

Если вы слышите много шума при выходе из других потоков, запишите windbg для продолжения работы после прерывания, если это не тот идентификатор потока, который вас интересует.

Изменить: Если вы считаете, что поток завершается изнутри вашего процесса, вы также можете установить точку останова на TerminateThread ( bp kernel32! TerminateThread ) и ExitThread ( bp kernel32! ExitThread ), чтобы поймать стек убийцы.

5
ответ дан 28 November 2019 в 02:52
поделиться

Вам следует инструментировать DoSomethingForALongLongTime() большим количеством отладочных логов, чтобы вы могли выяснить, в какой точке код прекращает выполнение. Или подключите отладчик и прерывайте все случайные исключения.

1
ответ дан 28 November 2019 в 02:52
поделиться

Это может быть одно из различных неустранимых исключений, включая Stack Overflow или Out of Memory. Эти исключения труднее всего отследить.

Как выглядит потребление памяти во время работы этого потока? Можете ли вы использовать профилировщик памяти, чтобы увидеть, не выходит ли он из-под контроля? Можете ли вы добавить логирование во внутренних циклах? Если у вас есть рекурсивный метод, добавьте счетчик и выбрасывайте исключение, если он повторяется невозможное количество раз. Используете ли вы большие объекты, которые могут быть причиной фрагментации кучи больших объектов (вызывает ошибки выхода из памяти, даже если на самом деле вы не вышли).

1
ответ дан 28 November 2019 в 02:52
поделиться

используйте AsyncTasks для выполнения длительной работы в asp.net

1
ответ дан 28 November 2019 в 02:52
поделиться

Когда вы вызываете 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);
 }
}
2
ответ дан 28 November 2019 в 02:52
поделиться

Попробуйте использовать событие app domain UnhandledException: http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx

это может дать вам некоторую информацию, если вы пропустите некоторые исключения

1
ответ дан 28 November 2019 в 02:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: