C
C#•2y 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•2y ago
where are you getting that error?
Lunar
LunarOP•2y ago
@ReactiveVeina " httpObject.Timeout = TimeSpan.FromSeconds(1);" @ReactiveVeina any idea ?
JakenVeina
JakenVeina•2y ago
where's the setter for that property?
Lunar
LunarOP•2y ago
can you join dev-vc-0 ?
JakenVeina
JakenVeina•2y ago
no
Lunar
LunarOP•2y ago
which property r u taking ?
JakenVeina
JakenVeina•2y ago
.Timeout
Lunar
LunarOP•2y ago
It is inbuild method of HttpClient
JakenVeina
JakenVeina•2y 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
LunarOP•2y ago
Let me check @ReactiveVeina Check now
JakenVeina
JakenVeina•2y ago
check what, the original message? you edited it?
Lunar
LunarOP•2y ago
@ReactiveVeina yes
JakenVeina
JakenVeina•2y ago
there is still no definition for Timeout in HttpClientObject
Lunar
LunarOP•2y ago
which line ?
JakenVeina
JakenVeina•2y ago
any line ah, okay, so it's changed on student
JakenVeina
JakenVeina•2y 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•2y 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
LunarOP•2y ago
Is there any alter solution ? Can`t I change the value during constructor or create a new object ?
JakenVeina
JakenVeina•2y ago
you can change the value during construction you would not want to create a new object
Lunar
LunarOP•2y ago
I am unable to figure how to pass to that constructor
JakenVeina
JakenVeina•2y ago
huh? what constructor?
Lunar
LunarOP•2y ago
HttpClientObject constructor
JakenVeina
JakenVeina•2y ago
what's that got to do with setting HttpClient.Timeout during construction?
Lunar
LunarOP•2y ago
For<AppsHttpClientSource>().LifecycleIs<SingletonLifecycle>().Use<HttpClientObject>().SelectConstructor(() => new HttpClientObject(CustomParameter)); Only at construction i can change value
JakenVeina
JakenVeina•2y ago
or when you can guarantee that nothing else is currently using it
Lunar
LunarOP•2y 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•2y ago
k
Lunar
LunarOP•2y ago
But unable to pass value of x
JakenVeina
JakenVeina•2y ago
why not?
Lunar
LunarOP•2y ago
I am unable to figure out
JakenVeina
JakenVeina•2y ago
figure out what?
Lunar
LunarOP•2y ago
how to pass x to HttpClientObject constructor
JakenVeina
JakenVeina•2y ago
the same way you pass anything to any constructor you even already have a CustomParameters object why not add it to that?
Lunar
LunarOP•2y ago
Can I create a separate method in HttpClientObject
JakenVeina
JakenVeina•2y ago
for what?
Lunar
LunarOP•2y 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•2y ago
what would that allow you to do?
Lunar
LunarOP•2y ago
if x condition it will create my custom client with passed value or else it will create default timeout value
JakenVeina
JakenVeina•2y ago
why would you create an entire new client object, which you're already probably mis-managing, just to change the default timeout?
Lunar
LunarOP•2y ago
yes, I am thinking I am doing something wrong
JakenVeina
JakenVeina•2y ago
yes, you likely are what is it that you're TRYING to do?
Lunar
LunarOP•2y ago
There multiple get calls for specific condition I want to increase timeout seconds
JakenVeina
JakenVeina•2y ago
so, you need to have different timeouts for different requests
Lunar
LunarOP•2y ago
yes, I think
JakenVeina
JakenVeina•2y ago
great, HttpClient supports that
Lunar
LunarOP•2y ago
A request - 10 s B request - default C request - deafult something like that
JakenVeina
JakenVeina•2y ago
k do that
Lunar
LunarOP•2y ago
how this would help ?
JakenVeina
JakenVeina•2y ago
because that's the mechanism by which HttpClient supports having custom timeouts for individual requests
Lunar
LunarOP•2y ago
like this ? CancellationTokenSource timeoutSource = new CancellationTokenSource(2000); await httpClient.GetAsync("http://www.foo.bar", timeoutSource.Token);
JakenVeina
JakenVeina•2y ago
pretty much
Lunar
LunarOP•2y 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•2y ago
nah, you'd omit the cancellation token entirely if you don't want a custom timeout
Lunar
LunarOP•2y ago
means ? example plz
JakenVeina
JakenVeina•2y 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
LunarOP•2y ago
It is for threading
JakenVeina
JakenVeina•2y ago
no it's for calling async methods within non-async code
Lunar
LunarOP•2y ago
await for result
JakenVeina
JakenVeina•2y ago
why do you need that
Lunar
LunarOP•2y ago
To compute multiple request
JakenVeina
JakenVeina•2y ago
no that is very much not a valid reason to have synchronous code doing asynchronous work
Lunar
LunarOP•2y ago
should I remove ?
JakenVeina
JakenVeina•2y ago
you should swap to async any code that needs to do async work
Lunar
LunarOP•2y ago
public async fun() { await work(); } like this
JakenVeina
JakenVeina•2y ago
pretty much that's got nothing to do with whether or not you also have parallelism whether physical or logical
Lunar
LunarOP•2y ago
hmm From where you have learn all this ?
JakenVeina
JakenVeina•2y ago
practice also, here also docs.microsoft.com
Lunar
LunarOP•2y 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•2y ago
looks okay to me
Accord
Accord•2y 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.

Did you find this page helpful?