1

What are the differences between these two fire-and-forget choices:

HostingEnvironment.QueueBackgroundWorkItem(async () => await UpdateStatsAsync(id))

and

HostingEnvironment.QueueBackgroundWorkItem(() => UpdateStatsAsync(id))

when it comes to queuing up some background work that the client doesn't really need to depend on?

Rob
  • 26,989
  • 16
  • 82
  • 98
DeepSpace101
  • 13,110
  • 9
  • 77
  • 127
  • 1
    Look at [this SO Question](http://stackoverflow.com/questions/36942716/why-use-async-with-queuebackgroundworkitem) – Icemanind Jan 23 '17 at 23:29
  • @Icemanind: Thanks, those answers aren't clear and also contradict each other. And Stephen Cleary's answer there talks about general async vs sync cases :/ – DeepSpace101 Jan 24 '17 at 00:18
  • The accepted answer is detailed and accurate. Cleary's answer is an odd contribution; doesn't really seem to address the practical elements of the question that was asked. But that doesn't mean that the question isn't an exact duplicate of yours. – Peter Duniho Jan 24 '17 at 01:29
  • 1
    Meh. You closed whilst I was answering. I record my answer here, if only to vent my spleen. The difference is that - the first one spuriously wraps UpdateStatsAsync() in an extra Task which later has to be unwrapped again. - the second one is easier to read. – Chris F Carroll Jan 24 '17 at 02:07
  • Reopening; this question is about two different ways to queue asynchronous work to QBWI; [the other question](http://stackoverflow.com/questions/36942716/why-use-async-with-queuebackgroundworkitem) is about queueing asynchronous work vs queueing synchronous work. – Stephen Cleary Jan 25 '17 at 00:53
  • Guys, this is very different from a standard question on return await. QBWI is the unknown vs a standard return – DeepSpace101 Jan 25 '17 at 00:56

1 Answers1

0

In this case I would use the non-async version, as HostingEnvironment.QueueBackgroundWorkItem has an overload that takes a CancellationToken and returns a Task, so your code would look like:

HostingEnvironment.QueueBackgroundWorkItem(ct => UpdateStatsAsync(id));

Internally this overload awaits this function for you. One downside to this approach is if you are returning the Task from inside a using scope, or try/catch, you might get surprises by not awaiting your Task, but in this simple scenario you shouldn't need to worry about this.

Stuart
  • 5,358
  • 19
  • 28
  • Those surprises because of the underlying `async void` implementation in `HostingEnvironment.QueueBackgroundWorkItem` ? – DeepSpace101 Jan 24 '17 at 00:16
  • It is similar yes, so if you have a `try`/`catch` for example, if you do not `await` the `Task` returning method inside the `try` block, you will return a `Task` which when awaited on will throw. You could easily be forgiven for thinking you were catching that error, but because you didn't await *inside* the `try` block, you will not catch the exception there. – Stuart Jan 24 '17 at 00:20