async/await - truly cancelling an await and series of await
-
5 марта 2012 г. 9:38
Hi,
For one of the use case I would like to set textbox with some value when user presses a button
void OnClick(yada yada)
textBox.Text = await GetData();
where GetData has a bunch of await calls
async Task<String> GetData(){
var x1 = await DoFunction1TaskAsync();
var x2 await DoFunction2TaskAsync(x1);
...
return somestring
}
1 - For my app, I do not disable the button when user clicks on it, this is so I can cancel the current operation if any, and start new operation). Question: when user hit the button reptitively, how can I truly and completely cancel the current running task such that old task's result is completely ignored (not updating the textbox text), before the next operation can continue.
I know i can use cancellation token to cancel tasks but then isn't there a chance that before the cancellation is acknowledged, the operation completes thus also completing await, which in turn queues the textbox.text = <xxx> on the UI thread, all from the older task that was cancelled? basically I do not want intermediate text on the textbox.
2 - also if we cancel one await task, how can I cancel the following await so they do not execute? i.e. in the case above if we cancel DoFunction1TaskAsync() i do not want DoFunction2TaskAsync() to execute (and not trigger exception when updating the textbox text because of cancellatino).
Maybe i do not understand task/cancellation well, but this would help me understand the intracacies.
Thanks,
Rohit
- Изменено RohitOn.Net 5 марта 2012 г. 11:42
Все ответы
-
5 марта 2012 г. 17:25Модератор
1. You need to use a CancellationTokenSource here. You would cancel the token source (on the running operation), then start the new one. This should prevent your old operation from completing (provided it's not already completed).
"I know i can use cancellation token to cancel tasks but then isn't there a chance that before the cancellation is acknowledged, the operation completes thus also completing await, which in turn queues the textbox.text = <xxx> on the UI thread, all from the older task that was cancelled? "
Not really - the issue is, if the other operation is completed, this will have already happened. Since you have your button click event on the UI thread, it can't happen simultaneously with any other UI thread operation - so (provided you check for the CancellationToken.IsCancellationRequested flag or throw if a cancellation is requested) you will be in one of two states - the text box operation will have already completed, or the new one will get cancelled.
2. You need to check your CancellationToken to see if cancellation has been requested before calling DoFunction2TaskAsync(). This lets you not call it. You can throw or just return at this point - it's up to you and what makes the most sense in your scenario.
Reed Copsey, Jr. - http://reedcopsey.com
If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".- Помечено в качестве ответа RohitOn.Net 6 марта 2012 г. 1:52
-
6 марта 2012 г. 1:53Thanks much.

