1
votes

I need to write a service with some complex behaviour like simultanious tasks and I'm facing an issue with.

I've written a sample in xUnit to show you the problem.

1 want to execute a task on a background, eventually start some child tasks. At a moment in time the task needs to be cancelled.

Therefore, I have the following in place:

[Fact]
public void ShouldWaitUnitTaskCompleted()
{
    Task.Factory.StartNew(() =>
    {
        while (!cancellationTokenSource.IsCancellationRequested)
        {
            Task.Delay(10000).Wait();
            TaskIsCompleted = true;
        }
    }, cancellationTokenSource.Token);

    Thread.Sleep(3000);

    cancellationTokenSource.Cancel();

    Assert.True(TaskIsCompleted);
}

}

However, the xUnit completes after 3 seconds (my thread sleep). In my task, I'm having a loop that say, as long as it's not a cancellation request delay if for 10 second.

So the behaviour I expect would be:

  • Start the application.
  • Start the task (since it's no cancellation request, a delay of 10 seconds will start).
  • Wait for 3 seconds and then cancel the token.
  • Wait for the task with the 10 second delay to complete and then exit.

Why doesn't my code wait for the 10 seconds frame to pass?

2
No background threads could exist when the main (foreground) thread had already exit after 3 seconds. Your app died already. You would have to Thread.Sleep the main thread for another 7+ seconds to resume other work. - Biscuits

2 Answers

4
votes

You don't await your Task which you create. Hence the execution of the code just continues on to the Thread.Sleep(3000).

2
votes

Cancel signals that cancellation has been requested.

It doesn't wait for all tasks to complete before allowing the cancelling code to carry on doing useful things - if you do want to wait for those tasks to respond, there are already mechanisms for you to do this, separately. So Cancel just does one job, and does it well.