5

Can I have all the options like OnlyOnRanToCompletion, OnlyOnCanceled, NotOnFaulted, etc. using async/await? I can't find examples on how to achieve the same results as using Tasks, for instance:

Task.Factory.StartNew(foo).ContinueWith(bar, TaskContinuationOptions.NotOnRanToCompletion);

I'm not sure if simple conditional or exception handling can manage all the continuation behaviors available in explicit Tasks.

natenho
  • 5,231
  • 4
  • 27
  • 52
  • Can you set the bit flags? You should be able to. Tbh, not sure what you are asking – Lews Therin Oct 22 '13 at 21:21
  • 2
    For the exception handling it's not needed; just use a `try/catch` block and you can write code like you write it like you would in any code virtually anywhere else. Why would you *want* to use that style instead? If you want to use something other than the "OnlyOn*" or "NotOn*" options, which do you need and why? – Servy Oct 22 '13 at 21:24
  • @natenho, if you really need it, you should be able to implement this behavior with a [custom awaiter](http://blogs.msdn.com/b/pfxteam/archive/2011/01/13/10115642.aspx). – noseratio Oct 22 '13 at 21:34
  • @Servy I just wanted to correlate features, just doing an exercise to find out the conversion effort and capabilities between raw TPL code and the _elegant_ async/await pattern. Basically, the question is "Can I get the same results with less code?". Because, after all, we know that it's TPL behind the scenes in both cases. – natenho Oct 23 '13 at 00:50
  • 1
    @natenho You can always replicate what `await` is doing using tasks, but not everything that can be done with explicit tasks can be done using `await`. – Servy Oct 23 '13 at 00:51

2 Answers2

12

Can I have all the options like OnlyOnRanToCompletion, OnlyOnCanceled, NotOnFaulted, etc. using async/await?

You don't need to.

Instead of copious syntax using bit flags and lambda continuations, await supports a very natural try/catch syntax:

try
{
  await foo();
}
catch
{
  bar();
  throw;
}

I'm not sure if simple conditional or exception handling can manage all the continuation behaviors available in explicit Tasks.

They naturally handle None, NotOnCanceled, NotOnFaulted, NotOnRanToCompletion, OnlyOnCanceled, OnlyOnFaulted, and OnlyOnRanToCompletion. Most of the other flags only make sense for parallel tasks, not asynchronous tasks. E.g., AttachedToParent, HideScheduler, and PreferFairness don't make sense in the async world; DenyChildAttach, LazyCancellation, and ExecuteSynchronously should always be specified in the async world; and LongRunning never should be.

Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810
  • Simple exception handling was my first approach for the NotOn* and is good to confirm that's ok. I'll have to take a closer look at the other flags to review the last part of your sentence ;) – natenho Oct 22 '13 at 23:13
  • I got here when I ran into a situation that I needed to specify the `HideScheduler` flag, and I couldn't. The scenario: an async method is called from a GUI thread, which GUI thread is blocked until the end of the async call. This results in a deadlock because the continuation is posted back to the (waiting & blocked) GUI thread. HideScheduler would save the day. Work-around: `new Task({async call},TaskCreationOptions.HideScheduler).Start()` and wait for this temporary task. – robert4 Apr 29 '14 at 15:19
  • I know that usually it's an ill design to have the GUI thread blocked during an async call, but this was a special program: mainly headless operations (imagine a backup task) with GUI used during development only to provide feedback -- invisible/disabled/blocked in production environment. – robert4 Apr 29 '14 at 15:20
  • 1
    I don't think `HideScheduler` does what you think it does (it doesn't do anything unless you're actually executing the task on a task scheduler). There are better options. Option 1) Make your UI asynchronous. Option 2) Create the task using `Task.Run`. Option 3) Use `ConfigureAwait(false)` to avoid the deadlock. – Stephen Cleary Apr 29 '14 at 15:26
  • @Stephen: you're right, I also realized it meanwhile. +1 for `ConfigureAwait()`, what I found by reading [stackoverflow.com/a/15022170](http://stackoverflow.com/a/15022170) and [Await, and UI, and deadlocks! Oh my!](http://blogs.msdn.com/b/pfxteam/archive/2011/01/13/10115163.aspx) – robert4 Apr 30 '14 at 08:21
0

I don't think so.

Async/await was not made to replace TPL all together, but to supplement it by making simple operations cleaner.
If you still need extra configuration, you'll have to stick to tasks, or you could try implementing a custom awaiter with this behavior.

K893824
  • 1,279
  • 8
  • 21