Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the proper way to programmatically close a WinForms application after a certain time?

Tags:

c#

winforms

I start my form in the usual way:

Application.Run(new MainForm());

I want it to open and run until a certain time, then close. I've tried the following but to no avail:

(1) In the Main method (were the Application.Run() statement is), I enter the following AFTER Application.Run()

while (DateTime.Now < Configs.EndService) { }

RESULT: It never gets hit.

(2) BEFORE Application.Run() I start a new Background Thread:

        var thread = new Thread(() => EndServiceThread()) { IsBackground = true };
        thread.Start();

where EndServiceThread is:

    public static void EndServiceThread()
    {
        while (DateTime.Now < Configs.EndService) { }
        Environment.Exit(0);
    }

RESULT: vshost32.exe has stopped working crash.

(3) In MainForm Tick Event:

        if (DateTime.Now > Configs.EndService)
        {
            this.Close();
            //Environment.Exit(0);
        }

RESULT: vshost32.exe has stopped working crash.

What is the proper way to achieve my goal? Again, I want to launch the Form, have it open & running until a certain time (Configs.EndService), then close.

Thank you, Ben.

like image 733
Ben Avatar asked Mar 19 '13 03:03

Ben


People also ask

How do I close a form in WinForms?

Form. Close() is one method in closing a winform. When 'Form. Close()' execute , all resources created in that form are destroyed.

Which of the following method is used to close the windows form application?

Exit method is called to exit your application. If you have validation code in either of these events that must be executed, you should call the Form.

How do you close an application in C#?

Application.Exit Run (WinForms applications), this method stops all running message loops on all threads and closes all windows of the application.

How do you close a form in Visual Basic?

If you want to close the form then use Me. Close() instead. The Load event will fire again when you create the new instance.


2 Answers

Create a Timer, and have it close the program in its event handler.

Say you want the application to shut down after 10 minutes. You initialize the timer with a period of 60,000 milliseconds. Your event handler becomes:

void TimerTick(object sender)
{
    this.Close();
}

If you want it to close at a specific date and time, you can have the timer tick once per second, and check DateTime.Now against the desired end time.

This will work because the TimerTick will execute on the UI thread. The problem with your separate thread idea was that Form.Close was called on a background thread, not the UI thread. That throws an exception. When you interact with UI elements, it has to be on the UI thread.

Your background thread idea probably would work if you called Form.Invoke to execute the Close.

You could also create a WaitableTimer object and set its event for the specific time. The Framework doesn't have a WaitableTimer, but one is available. See the article Waitable Timers in .NET with C#. Code is available at http://www.mischel.com/pubs/waitabletimer.zip

If you use the WaitableTimer, be advised that the callback executes on a background thread. You'll have to Invoke to synchronize with the UI thread:

this.Invoke((MethodInvoker) delegate { this.Close(); });
like image 171
Jim Mischel Avatar answered Sep 29 '22 04:09

Jim Mischel


How about something like this:

public partial class Form1 : Form
{
    private static Timer _timer = new Timer();

    public Form1()
    {
        InitializeComponent();
        _timer.Tick += _timer_Tick;
        _timer.Interval = 5000; // 5 seconds
        _timer.Start();            
    }

    void _timer_Tick(object sender, EventArgs e)
    {
        // Exit the App here ....
        Application.Exit();
    }
}
like image 22
Dimitar Dimitrov Avatar answered Sep 29 '22 02:09

Dimitar Dimitrov