Reputation: 739
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
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