private async void TriggerWeekChanged(Week currentWeek)
{
await LoadDataForSelectedWeek(currentWeek); //Split into multiple methods
}
In case a user hammers on the Change_Week
Button how can I cancel the current Task, and start a new one with the new paramerters ?
I tried like this:
private async Task Refresh(Week selectedWeek, CancellationToken token)
{
Collection.Clear();
await LoadDataFromDatabase();
token.ThrowIfCancellationRequested();
await ApplyDataToBindings();
token.ThrowIfCancellationRequested();
//Do some other stuff
}
Problem is:
In my Collection
I got data from multiple weeks when I hit the button to fast in a row.
Everything that is awaited will need to have visibility on that
CancellationToken
. If it is a customTask
that you wrote, it should accept it as an argument, and periodically within the function, check to see if it has been cancelled. If so, it should take any actions needed (if any) to stop or rollback the operation in progress, then callThrowIfCancellationRequested()
.In your example code, you propbably want to pass
token
in toLoadDataFromDatabase
andApplyDataToBindings
, as well as any children of those tasks.There may be some more advanced situations where you don't want to pass the same
CancellationToken
in to child tasks, but you still want them to be cancellable. In those cases, you should create a new, internal to theTask
,Cancellationtoken
that you use for child tasks.An important thing to remember is that
ThrowIfCancellationRequested
marks safe places within theTask
that theTask
can be stopped. There is no guaranteed safe way for the runtime to automatically detect safe places. If theTask
were to automatically cancel its self as soon as cancellation was requested, it could potentially be left in an unknown state, so it is up to developers to mark those safe locations. It isn't uncommon to have several calls to check cancellation scattered throughout yourTask
.I've just notice that your
TriggerWeekChanged
function isasync void
. This is usually considered an anti-pattern when it is used on something that is not an event handler. It can cause a lot of problems with tracking the completed status of theasync
operations within the method, and handling any exceptions that might be thrown from within it. You should be very weary of anything that is marked asasync void
that isn't an event handler, as it is the wrong thing to do 99%, or more, of the time. I would strongly recommend changing that toasync Task
, and consider passing in theCancellationToken
from your other code.