-1

What is the difference between

MyFireAndForgetMethod();   
public async void MyFireAndForgetMethod(){}

and

MyFireAndForgetMethod(); // Will have a warning here
public async Task MyFireAndForgetMethod(){}

I am not sure which to use for a FireAndForget call to a metric.

David Gourde
  • 3,709
  • 2
  • 31
  • 65
  • 1
    You've already identified one difference. You get a warning with the `async Task` method, and none with the other. "What is the difference" questions are generally too broad, as they invite a broad range of discussion and answers, without any clear resolution. And your question shows no real evidence that you've made any effort to investigate the differences yourself. The marked duplicate _does_ provide a significant amount of information regarding _some_ of the possible differences you might be interested in, as well as useful suggestions for how and why to deal with those differences. – Peter Duniho May 12 '20 at 22:17
  • I found this to be helpful, although it might not be the answer you were looking for: [C# async/await with/without awaiting (fire and forget)](https://stackoverflow.com/questions/46053175/c-sharp-async-await-with-without-awaiting-fire-and-forget) – Barns May 12 '20 at 22:27
  • If you read my answer before, I reworked it. – Christopher May 13 '20 at 01:40

2 Answers2

-1

You should never be writing a async void method, as you can not Await it. And you should always await a async, because otherwise you swallow Exceptions. If you got nothing sensible to return from a function, just return a instance of non-generic Task - and thus it can be awaited.

"Fire and Forget is fine - provided you never actually forget." With several forms of Multitasking, there is this whole issue with swallowing Exceptions. The TPL suffers as badly from it as Multithreading. The execution of a Task can throw exceptions. And those can be fatal ones, wich should never be caught - much less silently swallowed (forgotten). Normally you have to write exceptionally bad try/catch code, but for Multtiasking you have to actively avoid it. Task and Await, are how you avoid it (not actually forget). While async void is a (almost) guaranteed swallowing.

The Task instance carries the Exceptions in a neat list. Wait will re-throw them. No Exception is swallowed due to Multtiasking (you of course still got the otehr ways to mess that part up).

If you got no sensible place to await, you could write a child Task for the sole purpose of looking at and handling it's parents exceptions. But then you would still have to kill the process on Fatal or Boneheaded Excetpions and end up with duplicated Exception handlers. Better to await it all back at the main programm flow, where you hopefully got that global Logging code.

Christopher
  • 9,634
  • 2
  • 17
  • 31
  • While there is some good advice here, there's nothing that seems even remotely like an answer to the _question_ that was asked, i.e. _what's the difference between the two constructs_. – Peter Duniho May 12 '20 at 22:18
  • @PeterDuniho One never has a spot to throw excetpions. Wich is the *entire 2nd half* of my answer. The accepted answer in the duplicate is saying the same thing I do, in less words or detail. And never mentions that there might be effects **besides** the return value (the 1st half of my answer). – Christopher May 12 '20 at 23:15
  • _"One never has a spot to throw excetpions [sic]"_ -- huh? Either can throw exceptions wherever they want. And a `Task` that is never observed is no different exception-wise than an async method that doesn't return a `Task` at all. In either case, an exception that's thrown is unobserved. So, no...it's not even close to being true that the second paragraph in your answer in any way answers the question that was asked. – Peter Duniho May 13 '20 at 01:06
  • @PeterDuniho Did some rework. Does that answer the question properly? – Christopher May 13 '20 at 01:39
-1

The difference is async void is for fire and forget calls, usually event handlers, async Task ot async Task<T> is the normal case.

The Task object is for awaiting the completion of the method, retrieve the result and to catch the possbile exceptions with standard try and catch.

Christian Held
  • 2,321
  • 1
  • 15
  • 26
  • Fire and Forget will just swallow Exceptions and cause race conditons. It should never be a real thing in your code. – Christopher May 12 '20 at 22:14