Related to this answer,
If I truly do want to "Fire and Forget" a method that does return a task, and (for simplicity) let's assume that the method isn't expected to throw any exceptions. I can use the extension method listed in the answer:
public static void Forget(this Task task) { }
Using this approach, if there are bugs in action of the Task
that cause an exception to be thrown then when the unexpected exception is thrown, the exception will be swallowed and go unnoticed.
Question: Wouldn't it be more appropriate in this scenario for the extension method to be of the form:
public static async void Forget(this Task task) { await task; }
So that programming errors throw an exception and get escalated (usually bringing down the process).
In the case of a method with expected (and ignorable) exceptions, the method would need to become more elaborate (as an aside, any suggestions on how to construct a version of this method that would take a list of acceptable and ignorable exception types?)
Often in application development you want a process to call another thread and continue the process flow, without waiting for a response from the called thread. This pattern is called the “fire and forget” pattern.
Fire-and-Forget is most effective with asynchronous communication channels, which do not require the Originator to wait until the message is delivered to the Recipient. Instead, the Originator can pursue other tasks as soon as the messaging system has accepted the message.
The first type of messaging we'll consider is fire-and-forget methods, which are supported intrinsically by . NET Remoting and XML Web services. With fire-and-forget methods, the client sends a request message but the server never responds.
Fire and Forget - Runnable Tasks. Handle Rejected Execution. Retrieving value from computation - Callable. Scheduling tasks to run at a fixed time, after a delay or repeatedly.
It depends on the semantics you want. If you want to ensure exceptions are noticed, then yes, you could await
the task. But in that case it's not truly "fire and forget".
A true "fire and forget" - in the sense that you don't care about when it completes or whether it completes successfully or with error - is extremely rare.
Edit:
For handling exceptions:
public static async void Forget(this Task task, params Type[] acceptableExceptions) { try { await task.ConfigureAwait(false); } catch (Exception ex) { // TODO: consider whether derived types are also acceptable. if (!acceptableExceptions.Contains(ex.GetType())) throw; } }
Note that I recommend using await
instead of ContinueWith
. ContinueWith
has a surprising default scheduler (as noted on my blog) and Task.Exception
will wrap the actual exception in an AggregateException
, making the error handling code more cumbersome.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With