I think that his question would suit more on SO as it doesn't require explicitly a code review. This question is more about of how to correctly cancel a task instead of fixing apointing good pracrises, etc.. However you have made a great quest that deserves an answer:
if (task.Wait(timeout))
{
return result;
}
throw new TaskTimeoutException(string.Format("'{0}' timed out after {1}", taskName, timeout));
This will wait timeout milliseconds for the task completion however, the task may still continue, like @Jesse pointed out.
In tasks you are only able to cancel a task with a Cancelation Token Source. With a cancellation token source you will be getting a token that you may then use to cancel the task. That token must be passed through all methods, this also includes the method that makes the long computation you were interested to cancel. This is because that you must actively check if there was a cancelation request. You can do this by calling the ThrowIfCancellationRequested method.
So, in the end, you won't be able to cancel your previous code without at least adding a Cancellation token parameter and check for the cancellation with that.
Here follows the pattern of a method that supports cancellation:
public static int Sum(int[] values, CancellationToken token){
int acc = 0;
for(int i = 0; i < values.Length; ++i){
acc += values[i];
token.ThrowIfCancellationRequested(); //you may wish to do this verification less often, doing this every iteration will reduce performance
Thread.Sleep(100); //just simulate a longer task so you may know that it may be canceled before completing.
}
return acc;
}
And here is how you could request a cancelation:
public static void Main(string[] args){
CancellationTokenSource cancelSource = new CancellationTokenSource ();
CancellationToken token = cancelSource.Token;
int[] values = Enumerable.Range(0, 1000).ToArray();
Task.Factory.StartNew(()=> Sum(values, token), token)
.ContinueWith(t => {
if(!t.IsCanceled){ // you need to check canceled, otherwise a cancelation exception will be raised when getting Result
Console.WriteLine(t.Result);
}
});
cancelSource.Cancel();
}
Edit I noticed that I only talked about the cancellation and skipped the timeout, which was your real problem. Well, now that you know about how a task may be canceled you can use a technique similar to the one you were using: Wait with the timeout, and request a cancellation:
int[] values = Enumerable.Range(0, 1000).ToArray();
var src = new CancellationTokenSource();
Task.Factory.StartNew(() => Sum(values, src.Token), src.Token).Wait(timeout);
src.Cancel();
if(task.Wait(timeout))
line as documented here: msdn.microsoft.com/en-us/library/dd235606.aspx \$\endgroup\$