C
C#ā€¢14mo ago
Lunar

ā” HttpClient Error

I have class HttpClientObject that create object of HttpClient public class HttpClientObject{ private readonly HttpClient client; public HttpClientObject(CustomParameters parameter) { handler=new HttpClientHandler(){} client = new HttpClient(handler) { Timeout=parameter.timeout }; } public HttpClient GetClient() { return client; } } I have another class to fetch data public class student{ HttpClientObject httpClientObject {get;set;} HttpClient client = httpClientObject .GetClient(); //For X condition true it will timeout period 1 else by default if(x) { client .Timeout = TimeSpan.FromSeconds(1); } var result = client .GetAsync("url").GetAwaiter().GetResult(); } But I am getting error - "This instance has already started one or more requests. Properties can only be modified". Getting error because of changing the Timeout and throws InvalidOperationException . Is there any safe solution ?
71 Replies
JakenVeina
JakenVeinaā€¢14mo ago
where are you getting that error?
Lunar
Lunarā€¢14mo ago
@ReactiveVeina " httpObject.Timeout = TimeSpan.FromSeconds(1);" @ReactiveVeina any idea ?
JakenVeina
JakenVeinaā€¢14mo ago
where's the setter for that property?
Lunar
Lunarā€¢14mo ago
can you join dev-vc-0 ?
JakenVeina
JakenVeinaā€¢14mo ago
no
Lunar
Lunarā€¢14mo ago
which property r u taking ?
JakenVeina
JakenVeinaā€¢14mo ago
.Timeout
Lunar
Lunarā€¢14mo ago
It is inbuild method of HttpClient
JakenVeina
JakenVeinaā€¢14mo ago
no it's a property of httpObject which is of type HttpClientObject which is your class but which doesn't contain a definition for Timeout in the code you posted
Lunar
Lunarā€¢14mo ago
Let me check @ReactiveVeina Check now
JakenVeina
JakenVeinaā€¢14mo ago
check what, the original message? you edited it?
Lunar
Lunarā€¢14mo ago
@ReactiveVeina yes
JakenVeina
JakenVeinaā€¢14mo ago
there is still no definition for Timeout in HttpClientObject
Lunar
Lunarā€¢14mo ago
which line ?
JakenVeina
JakenVeinaā€¢14mo ago
any line ah, okay, so it's changed on student
JakenVeina
JakenVeinaā€¢14mo ago
HttpClient Class (System.Net.Http)
Provides a class for sending HTTP requests and receiving HTTP responses from a resource identified by a URI.
JakenVeina
JakenVeinaā€¢14mo ago
.Timeout is not thread-safe you can't call it safely when the object is being used across many threads the intention is that you only set the timeout during construction the error tells you exactly what the problem is: there's an ongoing request that the client was used for, and you can't change the timeout while that's happening
Lunar
Lunarā€¢14mo ago
Is there any alter solution ? Can`t I change the value during constructor or create a new object ?
JakenVeina
JakenVeinaā€¢14mo ago
you can change the value during construction you would not want to create a new object
Lunar
Lunarā€¢14mo ago
I am unable to figure how to pass to that constructor
JakenVeina
JakenVeinaā€¢14mo ago
huh? what constructor?
Lunar
Lunarā€¢14mo ago
HttpClientObject constructor
JakenVeina
JakenVeinaā€¢14mo ago
what's that got to do with setting HttpClient.Timeout during construction?
Lunar
Lunarā€¢14mo ago
For<AppsHttpClientSource>().LifecycleIs<SingletonLifecycle>().Use<HttpClientObject>().SelectConstructor(() => new HttpClientObject(CustomParameter)); Only at construction i can change value
JakenVeina
JakenVeinaā€¢14mo ago
or when you can guarantee that nothing else is currently using it
Lunar
Lunarā€¢14mo ago
public HttpClientObject(CustomParameters parameter) { handler=new HttpClientHandler(){} client = new HttpClient(handler) { x==1?1:Timeout=parameter.timeout }; } I want to do something like this
JakenVeina
JakenVeinaā€¢14mo ago
k
Lunar
Lunarā€¢14mo ago
But unable to pass value of x
JakenVeina
JakenVeinaā€¢14mo ago
why not?
Lunar
Lunarā€¢14mo ago
I am unable to figure out
JakenVeina
JakenVeinaā€¢14mo ago
figure out what?
Lunar
Lunarā€¢14mo ago
how to pass x to HttpClientObject constructor
JakenVeina
JakenVeinaā€¢14mo ago
the same way you pass anything to any constructor you even already have a CustomParameters object why not add it to that?
Lunar
Lunarā€¢14mo ago
Can I create a separate method in HttpClientObject
JakenVeina
JakenVeinaā€¢14mo ago
for what?
Lunar
Lunarā€¢14mo ago
public HttpClient GetCustomCLient(int seconds) { return new HttpClient(_handler) { Timeout = TimeSpan.FromSeconds(seconds) }; } //student if (x) { client = httpClientObject .GetCustomCLient(1); } else { client = httpClientObject .GetClient(); }
JakenVeina
JakenVeinaā€¢14mo ago
what would that allow you to do?
Lunar
Lunarā€¢14mo ago
if x condition it will create my custom client with passed value or else it will create default timeout value
JakenVeina
JakenVeinaā€¢14mo ago
why would you create an entire new client object, which you're already probably mis-managing, just to change the default timeout?
Lunar
Lunarā€¢14mo ago
yes, I am thinking I am doing something wrong
JakenVeina
JakenVeinaā€¢14mo ago
yes, you likely are what is it that you're TRYING to do?
Lunar
Lunarā€¢14mo ago
There multiple get calls for specific condition I want to increase timeout seconds
JakenVeina
JakenVeinaā€¢14mo ago
so, you need to have different timeouts for different requests
Lunar
Lunarā€¢14mo ago
yes, I think
JakenVeina
JakenVeinaā€¢14mo ago
great, HttpClient supports that
Lunar
Lunarā€¢14mo ago
A request - 10 s B request - default C request - deafult something like that
JakenVeina
JakenVeinaā€¢14mo ago
k do that
Lunar
Lunarā€¢14mo ago
how this would help ?
JakenVeina
JakenVeinaā€¢14mo ago
because that's the mechanism by which HttpClient supports having custom timeouts for individual requests
Lunar
Lunarā€¢14mo ago
like this ? CancellationTokenSource timeoutSource = new CancellationTokenSource(2000); await httpClient.GetAsync("http://www.foo.bar", timeoutSource.Token);
JakenVeina
JakenVeinaā€¢14mo ago
pretty much
Lunar
Lunarā€¢14mo ago
Then I can remove Timeout from HttpClientObject and student and then add this condition if(A) { CancellationTokenSource timeoutSource = new CancellationTokenSource(2000); var result = client .GetAsync("url",timeoutSource.Token).GetAwaiter().GetResult(); } else{ CancellationTokenSource timeoutSource = new CancellationTokenSource(default); var result = client .GetAsync("url",timeoutSource.Token).GetAwaiter().GetResult(); } }
JakenVeina
JakenVeinaā€¢14mo ago
nah, you'd omit the cancellation token entirely if you don't want a custom timeout
Lunar
Lunarā€¢14mo ago
means ? example plz
JakenVeina
JakenVeinaā€¢14mo ago
if (something)
{
using var timeoutSource = new CancellationTokenSource(TimeSpan.FromSeconds(2));

var result = await client.GetAsync(url, timeoutSource.Token);
}
else
{
var result = await client.GetAsync(url);
}
if (something)
{
using var timeoutSource = new CancellationTokenSource(TimeSpan.FromSeconds(2));

var result = await client.GetAsync(url, timeoutSource.Token);
}
else
{
var result = await client.GetAsync(url);
}
also, what the hell ass are you doing with .GetAwaiter.GetResult()
Lunar
Lunarā€¢14mo ago
It is for threading
JakenVeina
JakenVeinaā€¢14mo ago
no it's for calling async methods within non-async code
Lunar
Lunarā€¢14mo ago
await for result
JakenVeina
JakenVeinaā€¢14mo ago
why do you need that
Lunar
Lunarā€¢14mo ago
To compute multiple request
JakenVeina
JakenVeinaā€¢14mo ago
no that is very much not a valid reason to have synchronous code doing asynchronous work
Lunar
Lunarā€¢14mo ago
should I remove ?
JakenVeina
JakenVeinaā€¢14mo ago
you should swap to async any code that needs to do async work
Lunar
Lunarā€¢14mo ago
public async fun() { await work(); } like this
JakenVeina
JakenVeinaā€¢14mo ago
pretty much that's got nothing to do with whether or not you also have parallelism whether physical or logical
Lunar
Lunarā€¢14mo ago
hmm From where you have learn all this ?
JakenVeina
JakenVeinaā€¢14mo ago
practice also, here also docs.microsoft.com
Lunar
Lunarā€¢14mo ago
Thank you šŸ™‡šŸæ try { CancellationTokenSource timeoutSource = null; if (x) { //For A request timeoutSource = new CancellationTokenSource(TimeSpan.FromSeconds(3)); } else if(y) { //For B request timeoutSource = new CancellationTokenSource(TimeSpan.FromSeconds(5)); } //Reset request will default var result = await client.GetAsync(url, timeoutSource.Token); }catch() Is there anything else I need to change ? šŸ˜“
JakenVeina
JakenVeinaā€¢14mo ago
looks okay to me
Accord
Accordā€¢14mo ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.