Configure Response Time for GetStringAsync by HttpClient [duplicate] - xamarin.forms

I have the following implementation. And the default timeout is 100 seconds.
I wonder how can I able to change the default timeout?
HttpService.cs
public class HttpService : IHttpService
{
private static async Task GoRequestAsync<T>(string url, Dictionary<string, object> parameters, HttpMethod method,
Action<T> successAction, Action<Exception> errorAction = null, string body = "")
where T : class
{
using (var httpClient = new HttpClient(new HttpClientHandler()))
{
}
}
}

The default timeout of an HttpClient is 100 seconds.
HttpClient Timeout
You can adjust to your HttpClient and set a custom timeout duration inside of your HttpService.
httpClient.Timeout = 5000;
HttpClient Request Timeout
You could alternatively define a timeout via a cancellation token CancellationTokenSource
using (var cts = new CancellationTokenSource(new TimeSpan(0, 0, 5))
{
await httpClient.GetAsync(url, cts.Token).ConfigureAwait(false);
}
A few notes:
Making changes inside of the HttpClient will affect all requests. If you want to make it per request you will need to pass through your desired timeout duration as a parameter.
Passing an instance of CancellationTokenSource will work if it's timeout is lower than Timeout set by the HttpClient and HttpClient's timeout is not infinite. Otherwise, the HttpClient's timeout will take place.

client.Timeout = 5*1000; doesnt work because client.Timeout expects something of type: System.TimeSpan
I changed the Timeout value using:
client.Timeout = TimeSpan.FromSeconds(10); // Timeout value is 10 seconds
You can use other methods as well:
FromDays
FromHours
FromMilliseconds
FromMinutes
FromSeconds
FromTicks
Just for FYI:
Default value of Timeout property is 100 seconds

Since we don't see any task created with a timeout i cannot help.
But if you are using a System.Net.Http under the hood of your application than MSDN says:
The default value is 100,000 milliseconds (100 seconds).
You can than change the value of the HttpClient.Timeout property
clent.Timeout = 5*1000;

if your httpservice class had a dependency IHttpClient (which it should instead of newing up an httpclient) then you could change the default by set this property on your client when configuring services.
For example
services.AddHttpClient<IHttpService , HttpService >(x => x.Timeout = TimeSpan.FromSeconds(10));

Related

Does HttpGet, HttpPost abort() method aborts the request even if it is taking more time to establish the connection

I have a scenario where in certain cases request need to be terminated based on alternate configuration. From https://www.baeldung.com/httpclient-timeout I understood that we can set hard time out. However not sure how to test this.
Does the below code aborts the request with in given time even if there is a scenario of connection or socket or read timeout
HttpGet getMethod = new HttpGet(
"http://localhost:8080/httpclient-simple/api/bars/1");
int hardTimeout = 5; // seconds
TimerTask task = new TimerTask() {
#Override
public void run() {
if (getMethod != null) {
getMethod.abort();
}
}
};
new Timer(true).schedule(task, hardTimeout * 1000);
HttpResponse response = httpClient.execute(getMethod);
For instance if connection time out is set to 10 seconds and it is taking more than 10 seconds then does it terminate in 5 seconds. Similarly for other timeout scenarios.
If Apache httpclient library does not support this, is there an alternative?
Thanks in advance.
Look here for setting connection and read timeouts with apache http client.

Triggering a fallback using #HystrixProperty timeout for HTTP status codes and other exceptions

I have a function in my #Service class that is marked with #HystrixCommand.
This method acts as a client which sends a request to another service URL and gets back a response.
What I want to do is to trigger a fallback function when the response status code is anything other than 200. It will also trigger a fallback for any other exceptions (RuntimeExceptions etc.).
I want to do this by making use of the #HystrixProperty or #HystrixCommandProperty.
I want the client to ping the URL and listen for a 200 response status and if it does not get back a 200 status within a certain time-frame I want it to fallback.
If it gets back a 200 status normally within a certain time it should not trigger the fallback.
#HystrixCommand(fallbackMethod="fallbackPerformOperation")
public Future<Object> performOperation(String requestString) throws InterruptedException
return new AsyncResult<Object>() {
#Override
public Object invoke() {
Client client = null;
WebResource webResource = null;
ClientResponse response =null;
String results = null;
try{
client = Client.create();
webResource = client.resource(URL);
client.setConnectTimeout(10000);
client.setReadTimeout(10000);
response = webResource.type("application/xml")
.post(ClientResponse.class, requestString);
} finally {
client.destroy();
webResource = null;
}
return results;
}
};
}
I specifically want to make use of the #HystrixProperty or #HystrixCommandProperty so performing a check inside the method for response status code not being 200 and then throwing an Exception is not acceptable.
Instead of using Annotations will creating my own Command by extending the HystrixCommand Interface work?
Any ideas or resources for where I can start with this are more than welcome.
I don’t understand why you don’t want to check the response http status code and throw an exception if it is not 200? Doing that will give you the behaviour you desire. i.e. it will trigger a fall back for exceptions or non 200 responses.
You can set the timeout in the client, however I would opt for using the hystrix timeout values. That way you can use Archaius to dynamically change the value at runtime if desired.
You can use the Hystrix command annotation or extend the HystrixCommand class. Both options will provide you with your desired behaviour
Here is an example using the annotation.
#HystrixCommand(fallbackMethod = "getRequestFallback")
public String performGetRequest(String uri) {
Client client = Client.create();
WebResource webResource = client.resource(uri);
ClientResponse response = webResource.get(ClientResponse.class);
if (response.getStatus() != 200) {
throw new RuntimeException("Invalid response status");
}
return response.getEntity(String.class);
}
public String getRequestFallback(String uri) {
return "Fallback Value";
}

Changing my code to use async methods instead of sync methods will force my WebClient to never timeout (20 minute++)

I have 2 asp.net MVC web applications , as follow:-
ApplicationA . which is an Asp.net mvc-4 deployed under iis-8.
ApplicationB. which is an Asp.net mvc-5 deployed under iis-8.
now inside my ApplicationA i have the following method,which will call an action method (home/sync) on applicationB , as follow:-
public List<Technology> GetTechnology(int? currentfiltertype)
{
try
{
using (WebClient wc = new WebClient())
{
string url = currentURL + "home/sync?filtertype=" + currentfiltertype;
wc.Headers.Add("Authorization", token);
string json = wc.DownloadString(url);
List<Technology> result = JsonConvert.DeserializeObject<List<Technology>>(json);
return result;
}
}
catch (Exception e){}
}
now i have noted that when the WebClient calls the action method, and the method did not receive a response within around 2 minutes it will raise a timeout exception. But since the home/sync action method on web application B needs around 30 minutes to complete.. so i was searching for a solution to extend the web-client timeout period. so i tried changing my code to use async methods as follow,mainly by replacing wc.DownloadString with wc.DownloadStringTaskAsync as follow:-
public async Task<List<Technology>> GetTechnology(int? currentfiltertype)
{
try
{
using (WebClient wc = new WebClient())
{
string url = currentURL + "home/sync?filtertype=" + currentfiltertype;
wc.Headers.Add("Authorization", token);
string json = await wc.DownloadStringTaskAsync(url);
List<Technology> result = JsonConvert.DeserializeObject<List<Technology>>(json);
return result;
}
}
catch (Exception e) {}
}
and now seems the WebClient will never expired ... i tried calling the action method and the web client keep waiting for a response for more than 20 minutes without raising any timeout exception, then it received the response from web applicationB and everything worked well..
so can anyone advice why changing my code to use async methods as shown in the above code, caused the WebClient to not timeout ?? i can not understand the relation between using async logic and extending the timeout period for the web-client (not sure if the WebClient will ever timeout inside async methods!!)?
can anyone advice why changing my code to use async methods as shown in the above code, caused the WebClient to not timeout ??
The answer is a bit convoluted: WebClient is based on WebRequest, and HttpWebRequest's Timeout property is only honored for synchronous requests.
(noy sure if the WebClient will ever timeout inside async methods!!)?
It does not directly support asynchronous timeouts, but it does support (its own kind of) cancellation, which you can trigger after a timer.

ASP MVC How to deal with TaskCancelledException, extend timeout for PostAsJsonAsync

I'm currently working on a project where I have to make a post request to another API, which takes a significant amount of time (~30-60 seconds) to return. When I make the post request from my controller, I usually (90% of the time) get a TaskCancelledException when the request times out. I've tried using NoAsyncTimeout and AsyncTimeout with a large number but it doesn't seem to be working. The exception happens at the PostAsJsonAsync line of code. The code is below:
[HttpPost]
[ValidateAntiForgeryToken]
[NoAsyncTimeout]
public async Task<ActionResult> Create(...)
{
// processing code
HttpClient httpClient = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true });
HttpResponseMessage response = await httpClient.PostAsJsonAsync(requestUri, data);
var jsonResult = JObject.Parse(await response.Content.ReadAsStringAsync());
// processing result
}
Is there anything I should do to increase the timeout time? Or is there another problem with this post request?
NoAsyncTimeout and AsyncTimeout set timeouts for the request that is serviced by this action. It's probable that the POST to requestUri is the one that is timing out. Try setting HttpClient.Timeout.

ModernHttpClient Task Cancelled by Button Spamming

In our iOS App, we currently do not prevent the user from making infinite AsyncCalls on the HttpClient.
Everytime a button is pressed, the HttpClient fires a request and after presssing the button an extreme amount of times at High Speed (say 40 times in 5 seconds) the Threads start throwing canceled exceptions.
Every class that has to use a HttpClient roughly implements it like this:
var handler = new NativeMessageHandler { AllowAutoRedirect = false, UseCookies = false };
using (var httpClient = new HttpClient(handler)
{
BaseAddress = new Uri(this.serviceSettings.BaseUrl),
Timeout = TimeSpan.FromSeconds(this.serviceSettings.Timeout)
})
{
return await httpClient.GetAsync(url);
}
Either our usage (and implementation) of the HttpClient is correct and we should implement a simple GUI fix, or our understanding of the HttpClient is wrong and our implementation is wrong.

Resources