Wednesday, 18 September 2013

Async Task cancellation best practices: user versus program

Async Task cancellation best practices: user versus program

I'm working on a library which does some lazy idle background work on a UI
thread (it has to be that way because of the legacy COM use). The task can
be cancelled by the consuming app via cancellation token, or it can be
explicitly cancelled as a result of user action (via
IUserFeedback.Continue). I'm trying to follow the MSDN pattern for task
cancellation.
My question is, should I make the difference between cancellation by user
(and return false) and by the calling app (throw), as IdleWorker1 does. Or
should I treat both cases equally and just throw, as with IdleWorker2?
I don't have any strict requirements from the designers of the interface
(the task is essentially never ending, so they only care about how much
work has actually been done so far, and they're receiving the progress via
IUserFeedback.Continue).
In a nutshell, IdleWorker1:
interface IUserFeedback
{
bool Continue(int n);
}
class IdleWorker1
{
public async Task<bool> DoIdleWorkAsync(CancellationToken ct, int
timeSlice, IUserFeedback feedback)
{
bool more = true;
int n = 0;
while (more)
{
ct.ThrowIfCancellationRequested();
more = feedback.Continue(++n);
await Task.Delay(timeSlice);
}
return more;
}
}
IdleWorker2:
class IdleWorker2
{
public async Task DoIdleWorkAsync(CancellationToken ct, int timeSlice,
IUserFeedback feedback)
{
int n = 0;
for (;;)
{
ct.ThrowIfCancellationRequested();
if (!feedback.Continue(++n))
throw new TaskCanceledException();
await Task.Delay(timeSlice);
}
}
}

No comments:

Post a Comment