As @Paulo mentions in the comments, this depends entirely on the how the code is written. It is easy to write your own async code that never returns, and it is trivial to deadlock your application using platform APIs by doing a .Wait() from the UI thread.
Fundamentally, an async operation is a function that returns an object (often called a "promise" or a "future") and then that object either sets an event or calls a callback function at some future point in time (this is the "logical" return value of the async operation).
Either part of this could fail -- the initial function might never get around to returning the promise object, or the promise might never get around to calling the callback / setting the event.