-
Notifications
You must be signed in to change notification settings - Fork 2.1k
CancellationToken #5239
Comments
Use the |
Thank you. Same behaviour. I believe if you put a CancellationToken in your action method the model binder binds it to HttpContext.RequestAborted though. |
Yeah, using Mvc/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/Binders/CancellationTokenModelBinder.cs Line 29 in a5db011
|
some background here.. /cc @Tratcher in case he wants to add more The In old webapi, we used to provide a token that fired when the client disconnected, and this is what we model-bound by default. This led to the assumption that the right thing to do was to always use that token, and pass it into every API call that could accept it. This led to a lot of exception noise in logs for cases that you really can't troubleshoot. This also led to the wrong semantics in a lot of cases. Would you abort a database transaction if the client disconnects while it's processing? This is why we bind Use it in good health with this knowledge. |
Thank you for background and clarification. Makes sense to me now. |
Just to clarify. I understood that now |
/cc @Tratcher @davidfowl - where did we put the client disconnected token? |
@rynowak RequestAborted is ClientDisconnected, we haven't made any effort to separate them. That said, client disconnects can be difficult to detect. If the client disconnects gracefully (FIN), Kestrel won't detect it unless you send multiple writes and the client sends a RST in response. If the client disconnects with a RST first Kestrel should detect that and fire RequestAborted. WebListener currently triggers RequestAborted for FIN or RST. |
So is all the information that I've ever given out on this topic false then? |
@Tratcher We should do the same in Kestrel (i.e. fire the RequestAborted token for both FIN and RST). It's affecting SignalR right now. |
The order the RST comes in is irrelevant. If a RST is received with or without a prior FIN, RequestAborted will fire. RequestAborted will not fire with just a FIN from the client since the TCP connection is in a half-open CLOSE_WAIT state (i.e. it's still valid to write to the response). Maybe for HTTP we should treat CLOSE_WAIT as disconnected/aborted, but we should investigate to make sure this wouldn't break real clients. |
Is there any update on this issue? This is really important especially when you are dealing with disaster recovery situations where the majority of the request should not be processed (due to client disconnection). We have a microservice archuiteture and this can actually prevent a "snowball" effect. |
We are currently looking at changing the RequestAborted token for the next release. There's an open PR for this change at aspnet/KestrelHttpServer#1218. The RequestAborted token will still fire today given failed writes or a RST from the client. In some scenarios, it's possible to send keep alive messages to the client and check the RequestAborted token to more reliably ensure the connection is still alive. |
This was fixed in Kestrel. |
This definately used to work as I tried it when David Paquette wrote a blog post blog post about it. What release was this fixed in, I'm trying the following code with ASP.NET Core 1.1.1 and can't get this to work as expected.
|
@RehanSaeed - can you provide more information about what you mean by |
However, my code above does not show |
This only works in 2.0 not in 1.x |
Hello, robert |
It really has nothing to do with Ajax, there's currently no cancellation token that represents the lifetime of the client. If you want to cancel some sever side operation then you need to create a cancellation token with a timeout and pass that to whatever APIs you call. |
Hi David, I have the following async Action in my ASP.NET MVC Controller (see below) where I get some SQL as a parameter and execute that query and the user should have the possibility to press a button to cancel the running query if it takes to Long... can you give me a short example how to cancel the async Action from the client if I press a button please?
|
I have just installed VS2017 15.3 and the CORE 2.0 SDK. Created a new ASP.NET CORE 2.0 (CORE) APP, and implemented the CancellationToken in a method, and it still doesn't get triggered. I can even close the browser (Edge), and even then, the HttpContext.RequestAborted (CancellationToken) is not triggered. I've tried with IE, Chrome and Edge, no luck so far!? Any ideas?
public async Task<IActionResult> About(CancellationToken token)
{
try
{
ViewData["Message"] = "Your application description page.";
DateTime time = DateTime.Now;
await Task.Run(() =>
{
double s = -1;
while ((DateTime.Now - time).TotalSeconds < 10)
{
if (HttpContext.RequestAborted.IsCancellationRequested)
break; // NEVER GETS HIT!
token.ThrowIfCancellationRequested();
if (s != DateTime.Now.Second)
{
System.Diagnostics.Debug.WriteLine(DateTime.Now.ToString("HH:mm:ss") + " task running....");
s = DateTime.Now.Second;
}
}
}, token);
System.Diagnostics.Debug.Print("Task done"); // GETS HIT, EVEN WHEN EDGE IS CLOSED 1 SECOND AFTER THE REQUEST STARTED
}
catch (Exception ex)
{
System.Diagnostics.Debug.Print(ex.Message); // NEVER GETS HIT
}
return View();
} |
Ah! You're using IIS right? There's still an issue there aspnet/AspNetCoreModule#38 (unfortunately) |
Exactly... yes, i was using IIS Express, and yes, it works like a charm with the Kestrel server :) |
I am using kestrel and the example code above does not work. Seems FIDDLER was my problem (Im on Win10), not sure what it's doing in the background to mess with this but once it was off, i now get TaskCanceledException, which is just fine. |
Thanks for contacting us. We believe that the question you've raised have been answered. If you still feel a need to continue the discussion, feel free to reopen it and add your comments. |
Sorry if this has been asked before but i cant find any documentation on it. Is it possible in MVC6 to get a CancellationToken triggered when aborting an ajax request for example. IsCancellationRequested is always false. From what i understand this was possible in MVC4 and WebAPI, not MVC 5+6?
The text was updated successfully, but these errors were encountered: