Async and top level UI
More and more libraries are using async
calls where you are expected to in turn use await
to allow the maximum code concurrency. However, there are some contexts where the costs of making an asynchronous call is high enough that you may want to insulate your code from the asynchronous nature while using it in other contexts where it makes sense.
An example of this is a large system that I designed long before the async
keyword was available (.NET 2.0, to be precise) and the asynchronous model from that time was cumbersome enough that we generally avoided it. However, modern APIs are often designed to *only* provide asynchronous versions of their calls. (In our case, this is a mail provider with additional feature above the normal SMTP senders.) In .NET 4.5 MVC, this situation is easy to manage as you can mark the controller itself as async
and the calls can be made easily with maximum concurrency and minimal debugging issues introduced. However, WinForms only allows events to be marked async void
which complicates debugging considerably. Additionally, changing the API surface to Async only makes the integration "big bang", forcing the entire codebase to be moved at once. Here we can mark the non-async call obsolete
and migrate at a more natural pace.
In these cases, the best option I have been able to find is to make a wrapper that fully awaits the result, thus preventing code from running asynchronously in this context. We can achieve this using the "boolean parameter hack" which allows two surfaced calls to call the same underlying code, just awaiting the result and returning the completed version when called via the non async version. This allows migration to be more gradual (important when you have a half million lines of user code).