Note that there are some explanatory texts on larger screens.

plurals
  1. POAsync Void, ASP.Net, and Count of Outstanding Operations
    primarykey
    data
    text
    <p>I am trying to understand why an async void method in an ASP.Net application can result in the following exception, while it appears that async Task will not:</p> <pre><code>System.InvalidOperationException: An asynchronous module or handler completed while an asynchronous operation was still pending </code></pre> <p>I am relatively new to the world of async in .NET, but do feel like I've tried to run this one down via a number of existing resources, including all of the following:</p> <ul> <li><a href="https://stackoverflow.com/questions/8043296/whats-the-difference-between-returning-void-and-returning-a-task">What's the difference between returning void and returning a Task?</a></li> <li><a href="http://msdn.microsoft.com/en-us/magazine/gg598924.aspx" rel="noreferrer">It's All About the SynchronizationContext</a></li> <li><a href="http://social.msdn.microsoft.com/Forums/en-US/6dbc3f00-b302-4e6b-9b97-419bc242c0d8/async-syntactic-sugar-suggestions" rel="noreferrer">Async Syntactic Sugar Suggestions</a></li> <li><a href="http://channel9.msdn.com/Events/aspConf/aspConf/Async-in-ASP-NET" rel="noreferrer">Async in ASP.NET</a></li> </ul> <p>From these resources, I understand the best practice is to typically return Task and avoid async void. I also understand that async void increments the count of outstanding operations when the method is called and decrements it when it is completed. This sounds like at least part of the answer to my question. However, what I am missing is what happens when I return Task and why doing so makes things "work".</p> <p>Here is a contrived example to further illustrate my question:</p> <pre class="lang-cs prettyprint-override"><code>public class HomeController : AsyncController { // This method will work fine public async Task&lt;ActionResult&gt; ThisPageWillLoad() { // Do not await the task since it is meant to be fire and forget var task = this.FireAndForgetTask(); return await Task.FromResult(this.View("Index")); } private async Task FireAndForgetTask() { var task = Task.Delay(TimeSpan.FromSeconds(3)); await task; } // This method will throw the following exception: // System.InvalidOperationException: An asynchronous module or // handler completed while an asynchronous operation was still pending public async Task&lt;ActionResult&gt; ThisPageWillNotLoad() { // Obviously can't await a void method this.FireAndForgetVoid(); return await Task.FromResult(this.View("Index")); } private async void FireAndForgetVoid() { var task = Task.Delay(TimeSpan.FromSeconds(3)); await task; } } </code></pre> <p>On a related note, if my understanding of async void is correct, then isn't it kind of wrong to think of async void as "fire and forget" in this scenario since ASP.Net is not actually forgetting about it?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload