Vortex852456
Vortex852456

Reputation: 739

Windows task scheduler terminate program doesn't work on forms application

I developed a windows forms programm which also provides a batch-mode. It does some work depending on SQL-table entries (one operation for each entry).

This program is registered in the task scheduler.

If there is a lot of data, the program may run many hours.

The task has the following configuration:

Problem: The kill doesn't work, but the task scheduler server thinks that it did. So it starts a next task after 0-10 minutes. Causing multiple tasks running.

Reproduce a similar problem is luckily easy:

Result: Task scheduler says nothing is running - I can start the task again.

This is how my program is build up (this is an abstraced but working example for reproduction):

Program.cs

static void Main()
{
    new frmTest().Auto(args);
}

frmTest.cs

public partial class frmTest : Form
{
    public frmTest()
    {
        InitializeComponent();
    }

    public void Auto(string[] args)
    {
        CancellationTokenSource tokenSource = new CancellationTokenSource();

        // Run a task which is cancellable every second.
        Task task = Task.Run(() =>
        {
            for (int i = 0; i < 60; i++)
            {
                Thread.Sleep(1000);
                tokenSource.Token.ThrowIfCancellationRequested();
            }

        }, tokenSource.Token);

        // Cancel the task when Application is trying to exit.
        Application.ApplicationExit += (o,e)=>
        {
            tokenSource.Cancel(); 
        };

        // We have to wait here. If we wouldn't, the main process would immedially including the current running task - for which we want to wait
        Task.WaitAll(task);
    }
}

Note: This problem does NOT appear, if I don't use a Form (this was my first attempt for the abstract version). It must have something to do with the form, but I have no idea what it could be.

Is it possible to reproduce this while in debug mode? I mean sending a signal or something which tells the application to exit (no forced-exit).

Upvotes: 0

Views: 972

Answers (1)

Damien_The_Unbeliever
Damien_The_Unbeliever

Reputation: 239704

You should be using Application.Run() to start the application running. Then, you will not need to use Task.WaitAll() to "prevent" the application from exiting:

static void Main()
{
    var f = new frmTest().Auto(args);
    Application.Run(f);
}

But you may want to have, instead,

    // Cancel the task when Application is trying to exit.
    Application.ApplicationExit += (o,e)=>
    {
        tokenSource.Cancel(); 
    };

    Task.WhenAll(task).ContinueWith(_=>{
      Application.Exit();
    });
}

Upvotes: 1

Related Questions