Как зайти в Даркнет?!
25th January, 01:11
6
0
Как в tkinter из поля ввода Entry получить значение в одну переменную и обновить строку кнопкой, затем получить ещё одно введённое значение и затем сложить их. Ниже пример кода
21st July, 19:00
894
0
Программа, которая создает фейковые сервера в поиске игровых серверов CS 1.6 Steam
21st March, 17:43
948
0
Очень долго работает Update запрос Oracle
27th January, 09:58
914
0
не могу запустить сервер на tomcat HTTP Status 404 – Not Found
21st January, 18:02
905
0
Где можно найти фрилансера для выполнения поступающих задач, на постоянной основе?
2nd December, 09:48
938
0
Разработка мобильной кроссплатформенной военной игры
16th July, 17:57
1724
0
период по дням
25th October, 10:44
3955
0
Пишу скрипты для BAS только на запросах
16th September, 02:42
3720
0
Некорректный скрипт для закрытия блока
14th April, 18:33
4613
0
прокидывать exception в блоках try-catch JAVA
11th March, 21:11
4381
0
Помогите пожалуйста решить задачи
24th November, 23:53
6086
0
Не понимаю почему не открывается детальное описание продукта
11th November, 11:51
4350
0
Нужно решить задачу по программированию на массивы
27th October, 18:01
4396
0
Метода Крамера С++
23rd October, 11:55
4309
0
помогите решить задачу на C++
22nd October, 17:31
4002
0
Помогите решить задачу на python с codeforces
22nd October, 11:11
4492
0
Python с нуля: полное руководство для начинающих
18th June, 13:58
2599
0
Нить не просыпается от Thread.Sleep()
У нас есть служба Windows, написанная в C#. служба порождает поток, который делает это:
private void ThreadWorkerFunction()
{
while(false == _stop) // stop flag set by other thread
{
try
{
openConnection();
doStuff();
closeConnection();
}
catch (Exception ex)
{
log.Error("Something went wrong.", ex);
Thread.Sleep(TimeSpan.FromMinutes(10));
}
}
}
Мы поместили Thread.Sleep через пару раз, когда база данных ушла, и мы вернулись к файлам журналов 3GB, полным ошибок подключения к базе данных.
Это работает нормально в течение нескольких месяцев, но недавно мы видели несколько случаев, когда оператор log.Error() регистрирует исключение "System.InvalidOperationException: This SqlTransaction has completed; it is no longer usable", а затем никогда не возвращается. Служба может быть оставлена работать в течение нескольких дней, но больше ничего не будет зарегистрировано.
Сделав некоторое чтение, я знаю, что Thread.Sleep не идеален,но почему он просто никогда не вернется?
Покопаться и выяснить? Воткни отладчик в этого ублюдка!
Я вижу по крайней мере следующие возможности:
- входа в систему зависает;
- поток вышел просто отлично, но служба все еще работает, потому что какая-то другая часть имеет логическую ошибку.
И возможно, но почти наверняка нет, следующее:
- Sleep() висит.
Но в любом случае, прикрепление отладчика покажет вам, есть ли еще нить и действительно ли она зависла.
Мы вставили Thread.Sleep через пару раз, когда база данных исчезла, и мы вернулись к файлам журналов 3Gb, полным ошибок подключения к базе данных.
Мы вставили Thread.Sleep через пару раз, когда база данных исчезла, и мы вернулись к файлам журналов 3Gb, полным ошибок подключения к базе данных.
Я думаю, что лучшим вариантом было бы сделать так, чтобы ваша система ведения журнала ловила дубликаты, чтобы она могла написать что-то вроде: "The previous message was repeated N times".
Предположим, что я написал стандартную заметку о том, как вы должны открыть свое соединение в последний возможный момент и закрыть его при первой же возможности, а не охватывать потенциально огромную функцию так, как вы это сделали (но, возможно, это артефакт вашего демонстративного кода, и ваше приложение на самом деле написано правильно).
Когда вы говорите, что он сообщает об ошибке, которую вы описываете, вы имеете в виду, что этот обработчик сообщает об ошибке? Причина, по которой мне это непонятно, заключается в том, что в фрагменте кода Вы говорите "что-то пошло не так", но вы не сказали этого в своем описании; я бы не хотел, чтобы это было что-то настолько глупое, как исключение, которое ловится где-то еще, и код застревает где-то еще, кроме сна.
У меня была точно такая же проблема. Перемещение строки сна за пределы обработчика исключений исправило эту проблему для меня, как это:
bool hadError = false;
try {
...
} catch (...) {
hadError = true;
}
if (hadError)
Thread.Sleep(...);
Прерывание потоков, по-видимому, не работает в контексте обработчика исключений.
Вы пробовали использовать Monitor.Pulse (убедитесь, что ваш поток использует управление потоками перед запуском этого), чтобы заставить поток что-то делать? Если это сработает, то вам придется немного больше заглянуть в свою логику потоков.
Из кода, который вы опубликовали, не ясно, что после выброса исключения система определенно может перезапуститься - например, если исключение происходит из doStuff(), то поток управления вернется (после 10-минутного ожидания) в openConnection(), никогда не проходя через closeConnection().
Но, как уже говорили другие, просто подключите отладчик и найдите, где он на самом деле находится.
Я никогда полностью не понимал, что происходит, но это, казалось, было связано с ThreadInterruptedExceptions, выброшенным во время 10-минутного сна, поэтому я изменил код на:
private void ThreadWorkerFunction()
{
DateTime? timeout = null;
while (!_stop)
{
try
{
if (timeout == null || timeout < DateTime.Now)
{
openDatabaseConnections();
doStuff();
closeDatabaseConnections();
}
else
{
Thread.Sleep(1000);
}
}
catch (ThreadInterruptedException tiex)
{
log.Error("The worker thread was interrupted... ignoring.", tiex);
}
catch (Exception ex)
{
log.Error("Something went wrong.", ex);
timeout = DateTime.Now + TimeSpan.FromMinutes(10);
}
}
}
Помимо того, что он специально ловит ThreadInterruptedException,это просто чувствует себя безопаснее, поскольку все спящие происходят в блоке try, поэтому все неожиданные события будут регистрироваться. Я обновлю этот ответ, если когда-нибудь узнаю больше.