Может ли фоновый работник завершить работу сам по себе, когда он сталкивается с необработанным исключением, но служба продолжает работать? - PullRequest
0 голосов
/ 15 октября 2019

Настройка : 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
        }
    }

...