When canceling a task that has a timeout (before the timeout has ended) using a cancel token an exception is thrown. Example:
mytask.start();
bool didTaskRunInTime = mytask.wait(5 mins, _cancelToken);
Which means I cannot go on like below.
//was the task cancelled
if (_cancelToken.IsCancelRequested)
{
// log cancel from user to file etc
}
if (didTaskRunInTime )
{
int taskResult = myTask.Result;
// log result to file
}
else if (!_cancelToken.IsCancelRequested)
{
// Tell user task timed out , log a message etc
}
I will have to do all this in my catch block and my code is looking messy. What is the correct way to do this?
A task can be cancelled at any time by invoking cancel(boolean). Invoking this method will cause subsequent calls to isCancelled() to return true. After invoking this method, onCancelled(Object), instead of onPostExecute(Object) will be invoked after doInBackground(Object[]) returns.
TaskCanceledException(String, Exception, CancellationToken) Initializes a new instance of the TaskCanceledException class with a specified error message, a reference to the inner exception that is the cause of this exception, and the CancellationToken that triggered the cancellation.
Here is the sample code to cancel a task, CancellationTokenSource mCancellationTokenSource = new CancellationTokenSource();
You could call Task.WaitAny
with an array of just that task. Then you can act on the status of the task, however the method returns. Sample code:
using System;
using System.Threading;
using System.Threading.Tasks;
class Test
{
static void Main()
{
Task sleeper = Task.Factory.StartNew(() => Thread.Sleep(100000));
int index = Task.WaitAny(new[] { sleeper },
TimeSpan.FromSeconds(0.5));
Console.WriteLine(index); // Prints -1, timeout
var cts = new CancellationTokenSource();
// Just a simple wait of getting a cancellable task
Task cancellable = sleeper.ContinueWith(ignored => {}, cts.Token);
// It doesn't matter that we cancel before the wait
cts.Cancel();
index = Task.WaitAny(new[] { cancellable },
TimeSpan.FromSeconds(0.5));
Console.WriteLine(index); // 0 - task 0 has completed (ish :)
Console.WriteLine(cancellable.Status); // Cancelled
}
}
Note that if the task is faulted, you should "observe" the exception in order to avoid it going bang when it's finalized :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With