asp.net web-api add tag
Josh Darnell
I have an MVC 5 API controller running on .NET Framework 4.8 (you can find the full repro code [on GitHub](https://github.com/jadarnel27/AsyncVoidRaceConditionTest)), with the following `POST` method:

```
public IHttpActionResult Post([FromBody] string value)
{
    bool result = RegularMethod();
    return Json(result);
}

private bool RegularMethod()
{
    AsyncVoidMethod();
    return true;
}

private async void AsyncVoidMethod()
{
    await Task.Delay(2000);
}
```

There is a bug here, in that I've accidentally written an `async void` method which isn't `await`ed.  The result of that bug is that `AsyncVoidMethod()` is still running when the controller returns a 200 (success) response to the client (Google Chrome in this case).

The client code receives this success response, and makes a `PUT` request to the same API controller.  That action method looks like this:

```
public void Put(int id, [FromBody] string value)
{
    
}
```

The client code looks like this (using jQuery 3.5.1):

```
$.ajax({
    method: 'POST',
    url: 'https://localhost:44334/api/values',
    data: { value: "some thing" }
}).done(function () {
    $.ajax({
        method: 'PUT',
        url: 'https://localhost:44334/api/values/5'
    }).done(function () {
        
    }).fail(function () {
        
        $.ajax({
            method: 'PUT',
            url: 'https://localhost:44334/api/values/5'
        }).done(function () {
            
        })
    });
}).fail(function (xhr, status, error) {
    
});
```

As mentioned, the initial `POST` request succeeds.  But the first `PUT` request just kind of...hangs until the orphaned server-side task completes (two seconds later), and then gets an invalid response from the server (without ever running the `Put` action method):

![failed-put.png](/image?hash=8c5e059133e4d318be0800908bc3b7bb8ba2c1d25e4578cadabe5c8f4ee252d9)

You can see the two second pause on the `PUT` request in the screenshot above.  If you're curious about what the response actually is, I grabbed it with Wireshark, and it's this HTML file:

![put-error-page.png](/image?hash=5af13ef3bea7e86ed34405fa6db6b75232da9f627bd4fecb0e2018555c479ce4)

The error makes sense (that's exactly what has happened), but I don't understand why the server sends it in response to this unrelated request.

The JavaScript code immediately retries the `PUT` request, which succeeds without issue.

**My question:** why is the first `PUT` request seemingly blocked by the orphaned task, and why does the server send that error page in response to this unrelated request?

I realize the easy solution is to not use `async void`, `await` that method call, and the problem is resolved.  I'm curious about the underlying behavior that produces the strange results I've described though.

Additional information:

- If I shorten the delay (to 1 or 10 milliseconds), the `PUT` request succeeds some of the time (if the async task manages to get scheduled and complete before the second request is started)
- The same behavior occurs whether the server is running in local (full) IIS or IIS Express
- The errors vary - sometimes I get `ERR_METHOD_NOT_SUPPORTED` and other times I get `ERR_INVALID_HTTP_RESPONSE`
- The behavior appears to be client (or maybe protocol) specific
  - Chrome (and Chromium-based Edge) both attempt http/2 and fail, and then revert to http/1.1 after a page refresh. They both exhibit the behavior described above
  - IE 11 is able to use http/2, and both requests succeed
- This is a minimal repro of a real production scenario, in case that's important to anyone

Enter question or answer id or url (and optionally further answer ids/urls from the same question) from

Separate each id/url with a space. No need to list your own answers; they will be imported automatically.