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