简体   繁体   中英

Closing main app while form is running a thread

I have a C# windows application in which I create an instance of a some class, in which it has a member which is a window form and this form has a button that when I click it I open a new form that can run a worker thread, let's say:

public static void Main()
{
    MyClass mc = new MyClass();
    mc.ShowForm();
}

in MyClass.cs:

public void ShowForm()
{
    MyFirstForm firstForm = new MyFirstForm();
    firstForm.Show();
}

in MyFirstForm.cs:

private void myButton_Click(object sender, EventArgs e)
{
    MySecondForm secondForm =  new MySecondForm();
    secondForm.Show();
}

in MySecondForm.cs:

private void startButton_Click(object sender, EventArgs e)
{
    var worker = new Thread(StartWork);
    worker.Start();
}

private void stopButton_Click(object sender, EventArgs e)
{
    m_stopped = true;
}

private void StartWork()
{
    while(!m_stopped)
    {
       //work...
    }
}

When I run my app, clicks myButton, then click startButton, and then exit my app (I have a tray Icon that when clicked to exit, call base.Shutdown() ), the second form stays hanging and non responsive.

My original question was, what is the best way to notify the second form that it should close and stop the running thread, but during writing this post I noticed that I can use Task.Factory.StartNew(StartWork); and when I tried it, it worked without a hitch. So now I have another question which is why is this happening?

I tried registering to Closing , Closed , FormClosing events and setting m_stopped = true but they were not getting called.

EDIT: As @drf suggested the thread is a foreground thread hence the app is blocked while it runs, so adding:

worker.IsBackground = true;

fixed it.

I think for closing application you should use Application.Exit Method :

It informs all message pumps that they must terminate, and then closes all application windows after the messages have been processed.

Also you could track FormClosing event of each form. Check if Thread.IsAlive then Thread.Abort() or cancel closing.

Your thread is currently a foreground thread which will prevent the process from exiting until the thread finishes. http://msdn.microsoft.com/en-us/library/system.threading.thread.isbackground(v=vs.110).aspx

Change your thread startup code to this:

private void startButton_Click(object sender, EventArgs e)
{
    var worker = new Thread(StartWork);
    worker.IsBackground = true;
    worker.Start();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM