I'm aware that the best practice is to avoid async void
methods for anything but async event handlers, and there is quite strong expert opinion against other use cases. I was however just involved in a brief discussion about usefulness of async void
methods and I've got a couple of questions:
- How does the Framework keep track of pending
async void
methods, including event handlers? Is there possibly a way to obtain the current list of them or cancel them (EDITED: tracking is probably possible by installing a custom SynchronizationContext
)?
- Are they any useful for fire-and-forget logging scenarious? I think they actually may be, as long as the correct time-stamp is preserved at the beginning of the method, while it still executes synchronously.
How does the Framework keep track of pending async void methods, including event handlers?
The framework doesn't do anything special to keep track of async void methods. They're just like any other async method.
Also, your method either has a proper signature or it doesn't; event handlers do not care and have no logic to detect or work with async specifically.
A custom scheduler would be able to keep track of running tasks, but not have any specific knowledge if one is from an async void method or not. I don't think this is the right solution anyway -- if you find yourself needing to keep track of an async void method, you need to rethink your design.
Are they any useful for fire-and-forget logging scenarios? I think they actually may be, as long as the correct time-stamp is preserved
I don't know what you mean by a timestamp?
Async void is fine for any method where the caller will either never need to care about the result of the method call, or where it is being notified of the result elsewhere. These cases should be very exceedingly rare.
Fire-and-forget might be one such scenario, though I feel people often misuse fire-and-forget and end up just hiding important bugs from themselves.
Are they any useful for fire-and-forget logging scenarious?
Conceptually, I would say so, but if a task has an exception and it isn't being handled by waiting on it or accessing its Exception property which doesn't happen in an async void method it will tear down your application.
So I would avoid that.