3

I have a console app in C# that runs endlessly and looks something like this:

class Program
{
    static void Main(string[] args)
    {    
        while(true)
        {
            var listOfIds = GetItemIds();
            Parallel.ForEach(listOfIds,
                new Parallel { MaxDegreeOfParallelism = 15}, th => DoWork(th));
            Console.WriteLine("Iteration Complete");
        }
    }

    static void DoWork(int id)
    {
        //do some work and save data
    }

    static List<int> GetItemIds()
    {
        //return a list of ints
    }       
}

While a thread is in DoWork, it is processing data, modifying it and storing it. The app waits for all to finish and then goes again for a new iteration.

Now, if the console app is closed, it seems that threads do not finish their work and die with the console app. I thought threads created with Parallel were independent of the main thread. Is there a way to make the threads finish their work even if I exit the console app? should I use something different rather than Parallel to create the threads?

Theodor Zoulias
  • 34,835
  • 7
  • 69
  • 104
Oriol
  • 51
  • 5
  • 8
    Don't exit the console app. Threads belong to a *process*. You can't keep them alive once the process terminates. Perhaps you are looking for a way to create a service instead of a console application? – Panagiotis Kanavos Oct 09 '18 at 14:02
  • 3
    If the user wants to close your application let them close your application. Trying to run code when the user of the program doesn't want it to run is malware. Don't write malware. – Servy Oct 09 '18 at 14:04
  • 1
    The lifetime of your program is entirely controlled by the console. If the user presses Ctrl+C or Ctrl+Break or clicks the Close button then your program terminates and there is nothing you can do to stop that. If that matters then the console mode project template is not the best choice. Maybe it shouldn't matter, anything can be terminated by a trip over the power cord or judicious use of Task Manager. – Hans Passant Oct 09 '18 at 14:17
  • @Servy - this is about gracefully rounding up. You make "save file first?" into malware. – bommelding Oct 09 '18 at 14:20
  • 1
    @bommelding There's a big difference between asking if the user wants to save before closing and having the program just continue running silently even after the user thinks they've closed it. One is giving the user the *option* of doing something they likely mean to do before closing the application, without forcing them to, the other is intentionally subverting their instructions without their knowledge. – Servy Oct 09 '18 at 14:22

1 Answers1

3

A console app is going to kill all threads when the window is closed. Always. There is no way around that. The console window is directly linked to the process.

You may wish to use a Windows application which you will have more fine grained control over the main application loop. This could be a Windows Service or a WinForm/WPF type of application (which doesn't even really have to have a UI if you don't want).

If you want a Windows Application that still shows the console - this is a bit wonky, but you can find an example of how to do that here.

TheSoftwareJedi
  • 34,421
  • 21
  • 109
  • 151
  • yes, at first it was meant to be a service. But we got the idea to install it as a webjob in Azure as a continuous job. For that we need a console App. In any case you are right, if the user terminates the app it should be like that and make it end. I will find another way to make a "safe exit" to make the main thread break the endless loop or try and see if Azure can send events so the application can prepare to be closed. Thanks for the answer! – Oriol Oct 09 '18 at 14:21
  • I use web applications for webjobs. Works great. Just write a little api controller and have it spawn all the threads you want. – TheSoftwareJedi Oct 09 '18 at 16:02