1

This is my Program class:

static class Program
{
    private class MyAppContext : ApplicationContext
    {
        public MyAppContext()
        {
            //Exit delegate
            Application.ApplicationExit += new EventHandler(this.OnApplicationExit);

            //Show the main form
            MainForm main = new MainForm();
            main.Show();
        }

        private void OnApplicationExit(object sender, EventArgs e)
        {
            //Cleanup code...
        }
    }

    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new MyAppContext());
    }
}

When I'm running the app in debug mode and I close it, the main form closes, but the app is still running and I have to click on Stop Debugging to terminate it completely.

In the main form, all I do is:

protected override void OnFormClosed(FormClosedEventArgs e)
{
    base.OnFormClosed(e);
    Application.Exit();
}

What am I doing wrong?

Ivan-Mark Debono
  • 15,500
  • 29
  • 132
  • 263
  • Do you start any threads in your code? – Jon Skeet Apr 29 '15 at 08:15
  • 1
    You need to call ExitThread() when all forms are closed. – James Apr 29 '15 at 08:18
  • @JonSkeet No threads are started, although I have a static class with a`HttpClient ` instance in it. – Ivan-Mark Debono Apr 29 '15 at 08:18
  • If you could produce a short but *complete* example demonstrating the problem, that would really help... – Jon Skeet Apr 29 '15 at 08:19
  • [Here](http://stackoverflow.com/questions/8507978/exiting-a-c-sharp-winforms-applicatio),maybe there are some information helpful to you. – zhangyiying Apr 29 '15 at 08:20
  • Look in the Thread window (or Parallel Stacks) in Visual Studio while it "hangs" after all the windows are closed. You will see all the threads that haven't terminated. If any of those is not a background thread, that's your culprit. And since killing the threads didn't help, I'm pretty sure it's stuck waiting in native code for whatever signal - perhaps you have a custom socket with a blocking read, or you're executing some query on a database... Look through all the call stacks to find more information. – Luaan Apr 29 '15 at 08:28
  • 1
    That said, why are you using the `ApplicationContext` pattern? If you don't specifically need it, it's usually a better idea to just run `Application.Run(new MainForm());`. `ApplicationContext` is only really useful if you don't have a single main form - and it's pretty obvious that's not your case (since you call `Application.Exit` in `OnFormClosed` anyway). – Luaan Apr 29 '15 at 08:31
  • I remember profiling an app I wrote a while back where memory use kept growing every time I opened a form, but resources weren't released when the form was closed. The profiler helped me identify that I was not cleaning up event handlers correctly. Read the introduction of [this article](https://www.simple-talk.com/dotnet/.net-tools/profiling-the-memory-usage-of-a-.net-application-with-ants-memory-profiler-5/) and read on if you think it could be your issue. – Mr Moose Apr 29 '15 at 08:32
  • @Luaan Thanks for the suggestion. Threads and Parallel Stacks windows are both empty. However, in this solution, I'm starting 2 projects (Winforms and WebApi2). In the Processes window I see that iisexpress.exe is still running. Maybe that's the culprit. – Ivan-Mark Debono Apr 29 '15 at 08:35
  • @Ivan-MarkDebono, Did you try in "Project Options/Debug" main menu to uncheck the option "Enable Visual Studio hosting process"? – Alan Turing Apr 29 '15 at 08:38
  • VS hosting process can occasionally increse reference counter for managed resources and prevent to properly release of COM resources, if any being used by you applicaiton – Alan Turing Apr 29 '15 at 08:39
  • 1
    @Ivan-MarkDebono You souldn't close application in that way, it is incorrect – Alan Turing Apr 29 '15 at 08:41
  • @ArturMustafin It's only when I terminate the iisexpress.exe that the app really terminates. So I guess when running in release mode, it should work fine. – Ivan-Mark Debono Apr 29 '15 at 08:42
  • ... well, yeah. If you have multiple debug projects, they *all* have to exit for the debugger to shut down. Obvious in hindsight? :) – Luaan Apr 29 '15 at 08:53
  • @Ivan-MarkDebono That exactly means what i said - you have to to disable Visual Studio hosting process in project options – Alan Turing Apr 29 '15 at 09:41

3 Answers3

2

The problem is inheriting the AppContext, not sure why you need that. Suggest you do it normally without AppContext and cleanup in the MainForm_Closing, OnFormClosed, App_Exit or similar event.

public class Program
{
    [STAThread]
    private static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        //Application.Run(new MyAppContext()); <- no need
        Application.Run(new MainForm());
    }
}
Jeremy Thompson
  • 61,933
  • 36
  • 195
  • 321
0

EDIT:

This works fine for me. So it must be something else wrong. Post more code.

public class Program
{
    private class MyAppContext : ApplicationContext
    {
        public MyAppContext()
            : base(new Form())
        {
            //Exit delegate
            Application.ApplicationExit += new EventHandler(this.OnApplicationExit);

            MainForm.Show();
        }

        private void OnApplicationExit(object sender, EventArgs e)
        {
            //Cleanup code...
        }
    }

    [STAThread]
    private static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new MyAppContext());
    }
}
Andrei Tătar
  • 7,872
  • 19
  • 37
  • Neither this suggestion not the `ExitThread()` suggestion above work. – Ivan-Mark Debono Apr 29 '15 at 08:25
  • @Andrew: you omit valuable part: error comes from this part of code: protected override void OnFormClosed(FormClosedEventArgs e) { base.OnFormClosed(e); Application.Exit(); } – Alan Turing Apr 29 '15 at 08:42
0

Try that:

protected override void OnFormClosed(FormClosedEventArgs e)
{
    base.OnFormClosed(e);
    Environment.Exit(0);
}
Orkun Bekar
  • 1,447
  • 1
  • 15
  • 36