'Programs exits unexpectedly when trying to run in async or using a timer in C#

I am unable to trace the cause of the problem here. The program starts a service that runs continuously. While this runs I need to run another piece of code every 30 seconds that I can do it either by using a background worker or using a timer.

I tried using both timer and async background worker. However every time there is a callback after 30 seconds the program exits. The code is given below,

using log4net;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

[assembly: log4net.Config.XmlConfigurator(ConfigFile = "logger.xml", Watch = true)]

namespace Service.Envelope
{
    static class Program
    {
        private static readonly System.Timers.Timer Timer;
        private static readonly ILog LOGGER = LogManager.GetLogger(typeof(Program));
        private static Dictionary<int, int[]> MainCpseIdNodeIdDict = new Dictionary<int, int[]>();
        private static int[] NodeIds;
        private static int[] MainCpseIds;
        private static EnvelopeMainService envelopeMainService;

        private static void InitializeDict()
        {
            MainCpseIdNodeIdDict.Add(7, new int[] { 23476, 2276, 23472, 24498 });
            //MainCpseIdNodeIdDict.Add(9, new int[] { 23476, 2276, 23472, 24498 });
            MainCpseIds = new List<int>(MainCpseIdNodeIdDict.Keys).ToArray();
            NodeIds = new List<int>(MainCpseIdNodeIdDict.Values.SelectMany(x => x)).ToArray();
        }

        private static void StartBackgroundWorker()
        {
            LOGGER.Fatal("Starting bg worker..");
            BackgroundWorker work = new BackgroundWorker();
            work.DoWork += new DoWorkEventHandler(work_DoWork);
            work.RunWorkerAsync();
        }


        private static void work_DoWork(object sender, DoWorkEventArgs e)
        {
            while (true)
            {
                System.Threading.Thread.Sleep(30 * 1000);
                EnvelopeMainService.EnvelopeSwitch(false);
                Console.WriteLine("Generating data ..");
                envelopeMainService.GenerateBaseDataForGoodPart(); // program exits here
                System.Threading.Thread.Sleep(30 * 1000);  
            }
        }

        static void Main()
        {
            InitializeDict();
            LOGGER.MBLog("Start LOGGING");
            StartBackgroundWorker();
            EnvelopeMainService.SetUpTables();
            EnvelopeMainService envelopeMainService = new EnvelopeMainService(NodeIds, MainCpseIds);
            envelopeMainService.InitiateLiveEnvelope(MainCpseIdNodeIdDict);
        }
    }
}

The program exits at envelopeMainService.GenerateBaseDataForGoodPart(). This function calls a SQL function that loads the data to a datatable.

The timer version is given below. In both the versions the program exits at the same spot.

using log4net;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using System.Xml;

[assembly: log4net.Config.XmlConfigurator(ConfigFile = "logger.xml", Watch = true)]

namespace Service.Envelope
{
    static class Program
    {
        private static System.Timers.Timer Timer;
        private static readonly ILog LOGGER = LogManager.GetLogger(typeof(Program));
        private static Dictionary<int, int[]> MainCpseIdNodeIdDict = new Dictionary<int, int[]>();
        private static int[] NodeIds;
        private static int[] MainCpseIds;
        private static EnvelopeMainService envelopeMainService;

        private static void TimeIt()
        {
            Timer = new System.Timers.Timer(30000);
            Timer.AutoReset = false;
            Timer.Elapsed += OnTimedEvent;
            Timer.Start();
        }

        private static void InitializeDict()
        {
            MainCpseIdNodeIdDict.Add(7, new int[] { 23476, 2276, 23472, 24498 2276 });  
            MainCpseIds = new List<int>(MainCpseIdNodeIdDict.Keys).ToArray();
            NodeIds = new List<int>(MainCpseIdNodeIdDict.Values.SelectMany(x => x)).ToArray();
        }

        private static void StartService()
        {
            EnvelopeMainService.SetUpTables();
            envelopeMainService = new EnvelopeMainService(NodeIds, MainCpseIds);
            envelopeMainService.InitiateLiveEnvelope(MainCpseIdNodeIdDict);            
        }

        static void Main()
        {
            TimeIt();
            InitializeDict();
            LOGGER.MBLog("Start LOGGING");
            StartService();
        }

        private static void OnTimedEvent(object source, ElapsedEventArgs e)
        {
            Timer.Enabled = false;
            Timer.Stop();
            EnvelopeMainService.EnvelopeSwitch(false);            
            Console.WriteLine("Generating data ..");
            envelopeMainService.GenerateBaseDataForGoodPart(); // program exits here
            Console.WriteLine($"Data generated\n Starting live envelope");
            EnvelopeMainService.EnvelopeSwitch(true);
            Timer.Enabled = true;
            Timer.Start();                   
        }
    }
}



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source