Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

async/await cancellation mechanism

Tags:

c#

async-await

I have a question about what mechanism to cancel an ongoing async operation could be used, instead a cancellation token in the async/await context. I'm sure this is a well studied design decision that takes into account the imperative nature of the language, but in real situations having to pass a cancellation object to all your async methods is, at least, a bit painful. There are another design ideas from the c# community, or the proposed cancellation mechanism is just OK? I think I'm missing something.

like image 968
Masterile Avatar asked Feb 07 '11 21:02

Masterile


2 Answers

The cancellation token is the best practice, especially when the asynchronous process is expensive, has no preset ending condition, or involves external resources.

However, you can, if you wish, simply "give up". Instead of telling the async thread to abort processing and clean up, just "time out"; stop waiting for it to complete, detach any listeners, and keep running. When the thread eventually does complete, it'll check its event, realize nobody's listening, and silently terminate. The upside is the simplicity, however there are many situations in which this would be a BAD thing:

  • If the async process will keep processing forever unless you tell it to stop, it will keep running in the background, tying up CPU and other resources, until the app is closed, at which time the thread will be killed.
  • If the async thread is performing an abortable, reversible unit of work such as a DB operation, if the user presses cancel they expect anything done so far to have been rolled back. If you stop listening and move on, what they'll get is that what they thought they cancelled was performed.
  • In most cases, async operations involve external resources which take time to work with, and also require proper cleanup. Network sockets must be disconnected, DB connections closed, files unlocked, etc. Although giving up means you don't have to deal with that, instead letting the thread end normally, a common user experience is for the user to get fed up, hit cancel and then retry the operation. That means the resource you had used in the previous async operation has to be released to use it again.
like image 199
KeithS Avatar answered Oct 22 '22 16:10

KeithS


In order for cancellation of an async operation to make sense, that operation must perform discreet steps, since it is up the operation to check the cancellation token and stop itself from continuing. I.e. the cancellation token is merely a pattern to be implemented not a mechanism of async/await.

What that means it that if your async operation is just one I/O call with a completion handle, you might as well, just give up rather than cancel, since the operation will not have the oppurtunity to check your token until that call comes back at which point there is nothing to be gained.

So when considering a cancellation token, first consider whether this operation can be made more efficient by supporting cancellation or whether just not waiting for it to complete (i.e. using a timeout mechanism instead) makes more sense.

like image 30
Arne Claassen Avatar answered Oct 22 '22 15:10

Arne Claassen