Приложение С# неожиданно завершается

Мы запускаем консольное приложение С#, которое запускает несколько потоков для работы. Основная функция выглядит примерно так:

try
{
    DoWork();
}
catch (Exception err)
{
    Logging.Log("Exception " + err.ToString());
}
Logging.Log("Finished");

Функция DoWork() считывает новые задания из базы данных и порождает потоки для обработки одного рабочего элемента каждый. С прошлой недели приложение запустилось загадочно. Он исчезает из списка процессов и в журналах событий нет записи. Файл журнала показывает работу до определенной точки: он не регистрирует исключение или строку "Готово".

Любая подсказка о том, как приложение С# может обращаться в нуль?

EDIT: Темы создаются как:

new Thread(SomeObj.StartFunc).Start();

Некоторые из исчезновений возникают, когда нитки не работают.

P.S. Мы установили DebugDiag с правилом создания аварийного дампа всякий раз, когда наша программа разбилась. Он не создавал файлы дампа, когда процесс исчез.

Ответ 1

Какую идентификацию вы используете для запуска консольного приложения?

Также вы можете использовать SetConsoleCtrlHandler для захвата событий консоли. Посмотрите на это blog для получения дополнительной информации. У нас была аналогичная проблема, когда приложение Console было запущено под учетной записью службы, которое иногда прерывалось. Я не уверен, что это то, с чем вы столкнулись. Дайте мне знать, что я могу опубликовать код.

ОБНОВЛЕНИЕ: Похоже, сценарий похож на то, что мы пережили. В обработчике событий консоли вы должны проверить событие LogOff и вернуть true. Посмотрите на эту KB статью

public static void inputHandler(ConsoleCtrl.ConsoleEvent consoleEvent)
{
   if (ConsoleEvent == ConsoleCtrl.ConsoleEvent.CtrlLogOff)
       return true; 
   return false;
}

Ответ 2

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

Ответ 3

Возможно, что один из потоков, созданных методом DoWork, создает исключение. Поведение по умолчанию в этом случае заключается в завершении процесса. Вы можете остановить это, используя событие AppDomain.UnhandledException, чтобы переопределить поведение по умолчанию.

Ответ 4

возможно, это функция Logging.Log, которая генерирует ваше исключение?

Ответ 5

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

Чтобы он работал раньше, либо было что-то в DoWork(), чтобы ждать тех потоков, которые теперь возвращаются сразу (сломан) или эта часть все еще работает, но поток, который долгое время возвращался, теперь прерывается и сразу возвращается.

Ответ 6

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

Возможно ли, что вы вдруг пытаетесь обрабатывать гораздо больше данных, чем обычно, или используя процедуры повторного входа или "умные" с указателями?

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: мой опыт был с приложением Win32 С++, а не с С#.

Ответ 7

Может ли это быть утечкой памяти? Если ваше приложение занимает слишком много памяти, Windows его убьет. Вы можете проверить, сколько памяти вы используете: если она растет с течением времени, у вас может быть утечка памяти.

Другая возможность заключается в том, что где-то у вас есть код, вызывающий Environment.Exit(). Попробуйте выполнить полнотекстовый поиск через свой код, чтобы дважды проверить, вы никогда не знаете!

Ответ 8

Будьте осторожны, есть некоторые исключения, которые невозможно поймать: OutOfMemoryException, StackOverflowException, поэтому ваша программа умрет ужасно, но тихо.