Настройка : C #, .Net 4.5.2. Служба Windows;запускает 30 фоновых рабочих, которые удаляют элементы из внешней очереди и подключаются к БД для выполнения некоторой логики. Служба 32-разрядная, запущенная на 64-разрядном сервере Win 2012.
Проблема : По какой-то причине, если существует исключение SQL, все потоки перестают отвечать по очереди, нослужба показывает, что она все еще работает под services.msc.
Подробности : известно, что БД время от времени отключается, и в любой момент наша служба перестает работать. В большинстве случаев у нас нет выбора, кроме как перезапустить его вручную. Текущая база кода не использует события OnCompleted для перехвата исключения, и нет дополнительной логики для сброса потоков или чего-то подобного по этим линиям.
Что я не могу понять : Iя не могу понять, что, когда возникает исключение, фоновый рабочий продолжает работать, так что в этом случае, исключение SQL, он ожидает тайм-аут соединения по умолчанию, 15 или 30 секунд, а затем забывает об исключениичто только что произошло, и переходит к следующему пункту?
По какой-то причине мне кажется, что когда возникает исключение, этот поток становится практически бесполезным, и как только все потоки имеют дело с этим исключением, они на самом деле ничего не делают за кадром, но дляпо какой-то причине сама служба показывает, что она все еще работает и не выходит из системы.
Отладка на локальном : после отладки на локальном (VS) через несколько минутвсе потоки, кажется, существуют с кодом 0, и служба также существует, но я не могу увидеть это поведение на сервере.
Вопрос : Возможно ли, что всепотоки переднего плана умирают / ничего не делают, но сам сервис остается живым? Ребята, можете ли вы порекомендовать хороший способ сбросить все потоки, если возникает известное, но необработанное исключение?
Код :
Service.cs
protected override void OnStart(string[] args)
{
try
{
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;
for (int i = 0; i < 30; i++)
{
stt = new STF.STT();
stt.STP(check, i);
alBots.Add(stt);
count++;
check = false;
System.Threading.Thread.Sleep(3000);
}
}
catch (Exception err)
{
throw;
}
}
Начальная тема
public Boolean STP(bool check, int ctr)
{
threadCheck = check;
try
{
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;
bwAppprocessor = new BackgroundWorker();
bwAppprocessor.WorkerReportsProgress = true;
bwAppprocessor.RunWorkerCompleted += BwAppprocessor_RunWorkerCompleted;
bwAppprocessor.DoWork += BwAppprocessor_DoWork;
tmrPollChk = new System.Timers.Timer();
tmrPollChk.Elapsed += TmrPollChk_Elapsed;
tmrPollChk.Interval = Properties.Settings.Default.ThreadPollTimer;
tmrPollChk.Start();
bwAppprocessor.RunWorkerAsync();
return true;
}
catch (Exception err)
{
return false;
}
DoWork
private void BwAppprocessor_DoWork(object sender, DoWorkEventArgs e)
{
DoWorkProcesses();
}
Фактическая работа
void DoWorkProcesses()
{
try
{
//Business logic-connect to DB
return;
}
catch (Exception err)
{
//It logs error here
}
}
ONComplete
private void BwAppprocessor_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
try
{
//Not much going on here; no error handling :(
//or checking for e.Error :(
}
catch (Exception err)
{
//Useless
}
}