Подтвердить что ты не робот

Как узнать, кто убивает мои темы

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

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

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

EDIT: адресация ответов

  • Попробуйте/поймать Возможные исключения:
    Он реализован и ничего не ловит: (
  • Главная тема умирает:
    Этот поток создается веб-сервером, который продолжает работать
  • Завершение работы:
    Работа не завершена, так как она, наконец, влияет на базу данных, я могу проверить, было ли это сделано или нет, когда поток умирает.

Подумав об этих вещах, я довел меня до этого вопроса, кто убивает мои темы?

пс. Это не леди Голдент в гостиной со свечной палочкой:)

4b9b3361

Ответ 1

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

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

Ответ 2

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


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

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

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

Ответ 3

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

  • Загрузите Инструменты отладки для Windows, если у вас его еще нет.
  • Запустите windbg.exe, присоединитесь к вашему процессу.
  • Перерыв в windbg, введите sxe et, чтобы разрешить разрыв при выходе потока.
  • Когда отладчик прерывается, проверьте состояние системы, другие потоки и т.д.
  • Чтобы получить управляемый стек, загрузите файл sos.dll(.loadby sos mscorsvr, .loadby sos mscorwks или .loadby sos clr), затем запустите !clrstack (см. !help для других sos-команд)

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

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

Ответ 4

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

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

UPDATE

Ты сказал:

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

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

Ответ 5

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

Это веб-сервер butler.

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

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

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

Ответ 6

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

Ответ 7

Фоновый поток будет работать только до тех пор, пока не будут выполняться потоки foreground runnnig.

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

Ответ 8

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

Ответ 9

Простым ответом будет: "Убийца не оставляет карточку имени";)

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

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

Ответ 10

Вы можете увеличить значение executeTimeout для конфигурации \system.web\httpRuntime в web.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();.

Ответ 11

Когда вы вызываете 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);
 }
}

Ответ 12

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

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

Ответ 13

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

Ответ 14

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