views:

46

answers:

4

I have a task and I expect it to take under a second to run but if it takes longer than a few seconds I want to cancel the task.

For example:

Task t = new Task(() =>
        {
            while (true)
            {
                Thread.Sleep(500);
            }
        });
t.Start();
t.Wait(3000);

Notice that after 3000 milliseconds the wait expires. Was the task canceled when the timeout expired or is the task still running?

+2  A: 

The task is still running until you explicitly tell it to stop or your loop finishes (which will never happen).

You can check the return value of Wait to see this:

(from http://msdn.microsoft.com/en-us/library/dd235606.aspx) Return Value

Type: System.Boolean true if the Task completed execution within the allotted time; otherwise, false.

vdoogs
+1  A: 

Was the task canceled when the timeout expired or is the task still running?

No and Yes.

The timeout passed to Task.Wait is for the Wait, not the task.

Richard
+1  A: 

Task.Wait() waits up to specified period for task completion and returns whether task completed in specified amount of time (or early) or no. Task itself not modified and not rely on waiting.

Read nice series: Parallelism in .NET, Parallelism in .NET – Part 10, Cancellation in PLINQ and the Parallel class by Reed Copsey

And: .NET 4 Cancellation Framework / Parallel Programming: Task Cancellation

Check following code:

        var cts = new CancellationTokenSource();

        var newTask = Task.Factory.StartNew(state =>
                                   {
                                      var token = (CancellationToken)state;
                                      while (!token.IsCancellationRequested)
                                      {
                                      }
                                      token.ThrowIfCancellationRequested();
                                   }, cts.Token, cts.Token);


        if (!newTask.Wait(3000, cts.Token)) cts.Cancel();
Nick Martyshchenko
+1  A: 

If you want to cancel a Task, you should pass in a CancellationToken when you create the task. That will allow you to cancel the Task from the outside. You could tie cancellation to a timer if you want.

To create a Task with a Cancellation token see this example:

var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;

var t = Task.Factory.StartNew(() => {
    // do some work
    if (token.IsCancellationRequested) {
        // Clean up as needed here ....
    }
    token.ThrowIfCancellationRequested();
}, token);

To cancel the Task call Cancel() on the tokenSource.

Brian Rasmussen