You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
On .NET Framework 4.6.1 when using a Web API project Polly will wait the thread the request is running in for an indefinite amount of time, causing there to never be a response back to the client that called it. Calling the same method from a console app will work just fine.
This was tested using a freshly created solution in Visual Studio 'ASP.NET Web Application (.NET Framework)'.
I also tried this same code in .NET 5 and this issue is not present, it only happens on .NET Framework 4.6.1.
Expected behavior:
Polly policies should be executed without hanging the request.
Actual behaviour:
The request will become hung, and the client that called the API will never get a response.
Steps / Code to reproduce the problem:
PolicyContainer.cs:
publicclassPolicyContainer{publicIAsyncPolicy<HttpResponseMessage> CircutBreakerPolicy {get;set;}publicPolicyContainer(){
SetCircutBreakerPolicy();}privatevoidSetCircutBreakerPolicy(){//////////////////////////////////////////////////////////////////////////////////////// Normally these values would be set by a config file, hardcoded for this example. ////////////////////////////////////////////////////////////////////////////////////////// 0.5 means 50% of requests must fail before the circut breaksdoublefailureThreshold=0.5;// 60 means only the most recent 60 seconds are considered for breaking the circutdoublesamplingDuration=60;// 10 means at least this many calls must pass through the circut within the samplingDuration before breaking the circutintminimumThroughput=10;// 60 means the circut will be broken for 60 seconds after the threshold is metdoubledurationOfBreak=60;CircutBreakerPolicy= Policy.HandleResult<HttpResponseMessage>(result =>!result.IsSuccessStatusCode).AdvancedCircuitBreakerAsync(failureThreshold,
TimeSpan.FromSeconds(samplingDuration),
minimumThroughput,
TimeSpan.FromSeconds(durationOfBreak),
OnBreak,
OnReset,
OnHalfOpen);}privatevoidOnBreak(DelegateResult<HttpResponseMessage>response,TimeSpantimespan,Contextcontext){
Console.WriteLine("Circut Broken");}privatevoidOnReset(Contextcontext){
Console.WriteLine("Circut Reset");}privatevoidOnHalfOpen(){
Console.WriteLine("Circut Half-Open");}}
PollyTestRequest.cs:
publicclassPollyTestRequest{///////////////////////////////////////////////////////////////////////////////////////////////////////////// If set to true the Web API will never return a response, though any other type of project works fine. /////////////////////////////////////////////////////////////////////////////////////////////////////////////privateconstboolUSE_POLLY=true;publicstaticasyncTask<HttpResponseMessage>Send(){HttpClienthttpClient=new HttpClient();PolicyContainerpolicyContainer=new PolicyContainer();HttpResponseMessageresponse;if(USE_POLLY){// Does not work in a Web API application. // I stepped through the decompiled code this calls and it will arrive at a "public static bool Wait(object obj, int millisecondsTimeout, bool exitContext)" method.// Inside this method there is a call to "ObjWait(exitContext, millisecondsTimeout, obj)", however the debugger will not decompile this method so the debugging session will stop if you try to step into it.// The 'millisecondsTimeout' variable passed here will be "-1" and the 'exitContext' will be "null". I believe that this is what is hanging the thread indefinitely.// Its very strange though, calling this from a Console app, it will work fine, but from a Web API application it will hang indefinitely.response=await policyContainer.CircutBreakerPolicy.ExecuteAsync(async token =>await httpClient.PostAsync(new Uri("http://example.com"),new StringContent(""), token),
CancellationToken.None
);}else{// Works perfectly fine in both Web API and Console Appsresponse=await httpClient.PostAsync(new Uri("http://example.com"),new StringContent("")).ConfigureAwait(false);}returnresponse;}}
You're doing .Result on a Task from the ASP.NET controller.
This is a well-known way to create a deadlock when running under IIS in .NET Framework due to the way the threading model/synchronisation context works.
Change the controller method to be async and await the call, I'm pretty sure it will resolve the deadlock.
Summary:
.NET Version: .NET Framework 4.6.1
Polly Version: 7.2.2
On .NET Framework 4.6.1 when using a Web API project Polly will wait the thread the request is running in for an indefinite amount of time, causing there to never be a response back to the client that called it. Calling the same method from a console app will work just fine.
This was tested using a freshly created solution in Visual Studio 'ASP.NET Web Application (.NET Framework)'.
I also tried this same code in .NET 5 and this issue is not present, it only happens on .NET Framework 4.6.1.
Expected behavior:
Polly policies should be executed without hanging the request.
Actual behaviour:
The request will become hung, and the client that called the API will never get a response.
Steps / Code to reproduce the problem:
PolicyContainer.cs:
PollyTestRequest.cs:
TestController.cs:
The text was updated successfully, but these errors were encountered: