0

I am trying to figure out a way to shutdown my foreground thread in the event that my application quits/terminates/etc..

From what I have tested and read about, it is to my understanding that the main thread is always last to execute. Is this always true?

If so, then could someone suggest of a way to graciously signal a shutdown of a foreground thread? (in the event of application quit) Or is this even possible?

I am kinda getting a feeling that a foreground thread should be responsible of shutting down itself (not relying on a outside signal), unless it is known that the process will not terminate/shutdown prematurely. Is this also true?

I have a couple of reasons for using a foreground thread instead of a background thread:

  1. My thread allocates [ThreadStatic]native memory using Marshal.AllocHGlobal, and it needs to be properly released.

  2. It is a server application and preferably it would send all the queued packets before shutting down (not essential).

For example:

 volatile bool running = true;

 static void Main()
        {
            AppDomain.CurrentDomain.ProcessExit += new 
            EventHandler(OnProcessExit);
            var t = new Thread(ReadWrite);
            t.Start();
            ConsoleKeyInfo cki;
            Console.WriteLine("Running..\n");
            bool stopped = false;
            while(!stopped)
            {
                // do server stuff..
                   .......

                if (Console.KeyAvailable)
                {
                    cki = Console.ReadKey(true);
                    if (cki.Key == ConsoleKey.X)
                    {
                        stopped = true;
                    }
                }
            }
        }

    private void ReadWrite()
    {
        while (running)
        {
            // do stuff....
               ....

            Thread.Sleep(15);
        }
        FreeMemory();
    }


    public void EndServer()
    {
        FreeMemory();
        running = false;
        // do other stuff...
    }

    private void OnProcessExit(object sender, EventArgs e)
    {
        EndServer();
    }

This results in:

  • stopped is made true
  • OnProcessExit is not called. (I have also tried explicitly calling EndServer() but got the same result
  • application hangs

So I suspect (but I am not sure) that since the main thread is last to execute, the program is waiting for ReadWrite to finish, which means what I am doing is not possible?

If it is not possible, I will either: Look to see if it is possible to do with background thread, or I will look into redesigning my native memory implementation.

mkrieger1
  • 19,194
  • 5
  • 54
  • 65
Buretto
  • 405
  • 4
  • 12
  • 1
    Why are you worried about memory allocation (point 1)? When the program closes, that problem will solve itself. https://blogs.msdn.microsoft.com/oldnewthing/20120105-00/?p=8683 – mjwills Feb 27 '19 at 02:49
  • @mjwills Thank you, I really don't know how I didn't look for that ! I guess that solves my main issue (though I guess I never really had one). – Buretto Feb 27 '19 at 02:57
  • Reliably cleaning up on application closure is the one huge advantage Garbage Collection Memory Management has. As mywills said, do not bother with it. The second thing is that the question makes not a lot of sense. There is only one Foreground/Primary/GUI Thread and you do not start it. And it ending is the definition of the programm ending. It usually takes all background threads with it (at least in .NET). – Christopher Feb 27 '19 at 02:57
  • @Christopher AFAIK native memory not affected by GC (which is what caused my initial concern). Also you can definitely create foreground threads (default if creating threads as in my example), which is why in my case the program would not exit. Although looking at my question now, I can agree it really doesnt make much sense lol. – Buretto Feb 27 '19 at 03:04
  • @Bureto: If you got unmanaged resources, this is a question for the Finalize/Dispose pattern. And even if you do not need to finalize, you at least need to provide a dispose. That is the area where the GC, .NET code and unmanaged resources overlap. – Christopher Feb 27 '19 at 11:46

1 Answers1

1

It turns out I had no idea that native memory is freed when program is closed. Putting my thread in background will solve the rest of my issues.

Edit for future reference: A background thread did not solve point 2, though it was not essential for me so I went ahead with this solution anyways.

Buretto
  • 405
  • 4
  • 12