How to implement HttpClient in Xamarin.Forms applications using better CPU and Memory?
up vote
0
down vote
favorite
I am bit confused about all those problems and workarounds of httpclient usage in xamarin.forms. I would like to summarize my understanding and hesitations/questions
Disposing every time vs Singleton HttpClient and Static Client: It is said that dont use using around httpClient and use singleton implementation as stated in this article
Wrong;
var httpClient = new HttpClient(new HttpClientHandler
{
//Some settings
});
Correct:
public class HttpService
{
private readonly HttpClient _httpClient;
public HttpService()
{
_httpClient = CreateHttpClient();
}
Here the first question, if we dont use static what is the advantage of this?
Because HttpService will start a new client for each thread, not? If we use static client, will this cause any memory cycle?
Xamarin forms is very fragile about static dependency, if you are holding a static value inside a ViewModel and ViewModel is coupled with View using Freshmvvm, Prism etc., usually View wont be disposed and instance remains in the memory and causes memory leak even after popping the page.
DNS changes problem: it looks like that there is a problem to use singleton HttpClient whenever DNs changes as described here. How to overcome this problem in a xamarin.forms application? I dont see any ServicePointManager defined in .net standard 2.0. Do I really have to worry about this?
ReadAsStreamAsync vs ReadAsStringAsync when getting response. Does it make a big difference to use ReadAsStreamAsync? and is there any side effect to use as stream?
Should we dispose HttpResponseMessage with a using like below?
using (HttpResponseMessage response = await client.GetAsync(uri))
{
if (!response.IsSuccessStatusCode)
{
//Do something
}
else
{
//Do something
}
}
Finally my Class looks like as below; Do you see any problem with this?
proxy setting are described in this article
namespace myApp
{
public class HttpService
{
private readonly HttpClient client;
private JsonSerializer _serializer = new JsonSerializer();
public HttpService()
{
if (client == null)
{
try
{
HttpClientHandler handler = new HttpClientHandler
{
Proxy = Xamarin.Forms.DependencyService.Get<IProxyInfoProvider>().GetProxySettings()
};
client = new HttpClient(handler);
}
catch (Exception ex)
{
}
}
}
public async Task<T> GetItemAsync<T>(string url, CancellationToken cancellationToken=default(CancellationToken))
{
T returnObject = default(T);
Uri uri = new Uri(url);
try
{
using (HttpResponseMessage response = await client.GetAsync(uri,cancellationToken))
{
if (!response.IsSuccessStatusCode)
{
//Handle error
}
else
{
returnObject = await getReturnObject<T>(response);
}
}
}
catch (OperationCanceledException)
{
}
catch (System.Net.Http.HttpRequestException)
{
}
catch (Exception ex)
{
}
return returnObject;
}
public async Task<T> getReturnObject<T>(HttpResponseMessage response)
{
T returnObject = default(T);
if (response.IsSuccessStatusCode)
{
using (System.IO.Stream stream = await response.Content.ReadAsStreamAsync())
using (System.IO.StreamReader reader = new System.IO.StreamReader(stream))
using (JsonTextReader json = new JsonTextReader(reader))
{
returnObject = _serializer.Deserialize<T>(json);
}
//string content = await response.Content.ReadAsStringAsync();
//returnObject = JsonConvert.DeserializeObject<T>(content);
}
return returnObject;
}
}
}
xamarin xamarin.forms httpclient asp.net-core-webapi
|
show 1 more comment
up vote
0
down vote
favorite
I am bit confused about all those problems and workarounds of httpclient usage in xamarin.forms. I would like to summarize my understanding and hesitations/questions
Disposing every time vs Singleton HttpClient and Static Client: It is said that dont use using around httpClient and use singleton implementation as stated in this article
Wrong;
var httpClient = new HttpClient(new HttpClientHandler
{
//Some settings
});
Correct:
public class HttpService
{
private readonly HttpClient _httpClient;
public HttpService()
{
_httpClient = CreateHttpClient();
}
Here the first question, if we dont use static what is the advantage of this?
Because HttpService will start a new client for each thread, not? If we use static client, will this cause any memory cycle?
Xamarin forms is very fragile about static dependency, if you are holding a static value inside a ViewModel and ViewModel is coupled with View using Freshmvvm, Prism etc., usually View wont be disposed and instance remains in the memory and causes memory leak even after popping the page.
DNS changes problem: it looks like that there is a problem to use singleton HttpClient whenever DNs changes as described here. How to overcome this problem in a xamarin.forms application? I dont see any ServicePointManager defined in .net standard 2.0. Do I really have to worry about this?
ReadAsStreamAsync vs ReadAsStringAsync when getting response. Does it make a big difference to use ReadAsStreamAsync? and is there any side effect to use as stream?
Should we dispose HttpResponseMessage with a using like below?
using (HttpResponseMessage response = await client.GetAsync(uri))
{
if (!response.IsSuccessStatusCode)
{
//Do something
}
else
{
//Do something
}
}
Finally my Class looks like as below; Do you see any problem with this?
proxy setting are described in this article
namespace myApp
{
public class HttpService
{
private readonly HttpClient client;
private JsonSerializer _serializer = new JsonSerializer();
public HttpService()
{
if (client == null)
{
try
{
HttpClientHandler handler = new HttpClientHandler
{
Proxy = Xamarin.Forms.DependencyService.Get<IProxyInfoProvider>().GetProxySettings()
};
client = new HttpClient(handler);
}
catch (Exception ex)
{
}
}
}
public async Task<T> GetItemAsync<T>(string url, CancellationToken cancellationToken=default(CancellationToken))
{
T returnObject = default(T);
Uri uri = new Uri(url);
try
{
using (HttpResponseMessage response = await client.GetAsync(uri,cancellationToken))
{
if (!response.IsSuccessStatusCode)
{
//Handle error
}
else
{
returnObject = await getReturnObject<T>(response);
}
}
}
catch (OperationCanceledException)
{
}
catch (System.Net.Http.HttpRequestException)
{
}
catch (Exception ex)
{
}
return returnObject;
}
public async Task<T> getReturnObject<T>(HttpResponseMessage response)
{
T returnObject = default(T);
if (response.IsSuccessStatusCode)
{
using (System.IO.Stream stream = await response.Content.ReadAsStreamAsync())
using (System.IO.StreamReader reader = new System.IO.StreamReader(stream))
using (JsonTextReader json = new JsonTextReader(reader))
{
returnObject = _serializer.Deserialize<T>(json);
}
//string content = await response.Content.ReadAsStringAsync();
//returnObject = JsonConvert.DeserializeObject<T>(content);
}
return returnObject;
}
}
}
xamarin xamarin.forms httpclient asp.net-core-webapi
that should be a static constructor in the second snippet ofHttpService. Both of those snippets basically do the same thing
– Nkosi
Nov 19 at 23:54
@Nkosi so you suggest to change HttpService with static constructor and HttpClient static as well in this case. what will be the advantage and can this cause any memory leak if i use it as static?
– batmaci
Nov 20 at 0:03
I am saying that the example where you say it is correct way to use client is wrong.
– Nkosi
Nov 20 at 0:05
1
The second snippet does not prevent you from creating a second instance of HttpService which will create a second instance of HttpClient. If you want a true singleton. here's a nice in depth article on to do it: csharpindepth.com/Articles/General/Singleton.aspx
– jgoldberger - MSFT
Nov 20 at 0:08
2
A static member will remain in the heap memory for the life of the application. This is not a memory leak as it is always accessible. A memory leak occurs when you have an instantiated object that you no longer have a reference to so that you can no longer use it, access it, or dispose of it, but it is still in memory. So no, you don't have to worry about a memory leak, but the instance will stay in memory until you explicitly dispose it, or until the app is terminated. But you will only ever have the one instance, so not a big worry that it lives for the life of the app.
– jgoldberger - MSFT
Nov 20 at 0:58
|
show 1 more comment
up vote
0
down vote
favorite
up vote
0
down vote
favorite
I am bit confused about all those problems and workarounds of httpclient usage in xamarin.forms. I would like to summarize my understanding and hesitations/questions
Disposing every time vs Singleton HttpClient and Static Client: It is said that dont use using around httpClient and use singleton implementation as stated in this article
Wrong;
var httpClient = new HttpClient(new HttpClientHandler
{
//Some settings
});
Correct:
public class HttpService
{
private readonly HttpClient _httpClient;
public HttpService()
{
_httpClient = CreateHttpClient();
}
Here the first question, if we dont use static what is the advantage of this?
Because HttpService will start a new client for each thread, not? If we use static client, will this cause any memory cycle?
Xamarin forms is very fragile about static dependency, if you are holding a static value inside a ViewModel and ViewModel is coupled with View using Freshmvvm, Prism etc., usually View wont be disposed and instance remains in the memory and causes memory leak even after popping the page.
DNS changes problem: it looks like that there is a problem to use singleton HttpClient whenever DNs changes as described here. How to overcome this problem in a xamarin.forms application? I dont see any ServicePointManager defined in .net standard 2.0. Do I really have to worry about this?
ReadAsStreamAsync vs ReadAsStringAsync when getting response. Does it make a big difference to use ReadAsStreamAsync? and is there any side effect to use as stream?
Should we dispose HttpResponseMessage with a using like below?
using (HttpResponseMessage response = await client.GetAsync(uri))
{
if (!response.IsSuccessStatusCode)
{
//Do something
}
else
{
//Do something
}
}
Finally my Class looks like as below; Do you see any problem with this?
proxy setting are described in this article
namespace myApp
{
public class HttpService
{
private readonly HttpClient client;
private JsonSerializer _serializer = new JsonSerializer();
public HttpService()
{
if (client == null)
{
try
{
HttpClientHandler handler = new HttpClientHandler
{
Proxy = Xamarin.Forms.DependencyService.Get<IProxyInfoProvider>().GetProxySettings()
};
client = new HttpClient(handler);
}
catch (Exception ex)
{
}
}
}
public async Task<T> GetItemAsync<T>(string url, CancellationToken cancellationToken=default(CancellationToken))
{
T returnObject = default(T);
Uri uri = new Uri(url);
try
{
using (HttpResponseMessage response = await client.GetAsync(uri,cancellationToken))
{
if (!response.IsSuccessStatusCode)
{
//Handle error
}
else
{
returnObject = await getReturnObject<T>(response);
}
}
}
catch (OperationCanceledException)
{
}
catch (System.Net.Http.HttpRequestException)
{
}
catch (Exception ex)
{
}
return returnObject;
}
public async Task<T> getReturnObject<T>(HttpResponseMessage response)
{
T returnObject = default(T);
if (response.IsSuccessStatusCode)
{
using (System.IO.Stream stream = await response.Content.ReadAsStreamAsync())
using (System.IO.StreamReader reader = new System.IO.StreamReader(stream))
using (JsonTextReader json = new JsonTextReader(reader))
{
returnObject = _serializer.Deserialize<T>(json);
}
//string content = await response.Content.ReadAsStringAsync();
//returnObject = JsonConvert.DeserializeObject<T>(content);
}
return returnObject;
}
}
}
xamarin xamarin.forms httpclient asp.net-core-webapi
I am bit confused about all those problems and workarounds of httpclient usage in xamarin.forms. I would like to summarize my understanding and hesitations/questions
Disposing every time vs Singleton HttpClient and Static Client: It is said that dont use using around httpClient and use singleton implementation as stated in this article
Wrong;
var httpClient = new HttpClient(new HttpClientHandler
{
//Some settings
});
Correct:
public class HttpService
{
private readonly HttpClient _httpClient;
public HttpService()
{
_httpClient = CreateHttpClient();
}
Here the first question, if we dont use static what is the advantage of this?
Because HttpService will start a new client for each thread, not? If we use static client, will this cause any memory cycle?
Xamarin forms is very fragile about static dependency, if you are holding a static value inside a ViewModel and ViewModel is coupled with View using Freshmvvm, Prism etc., usually View wont be disposed and instance remains in the memory and causes memory leak even after popping the page.
DNS changes problem: it looks like that there is a problem to use singleton HttpClient whenever DNs changes as described here. How to overcome this problem in a xamarin.forms application? I dont see any ServicePointManager defined in .net standard 2.0. Do I really have to worry about this?
ReadAsStreamAsync vs ReadAsStringAsync when getting response. Does it make a big difference to use ReadAsStreamAsync? and is there any side effect to use as stream?
Should we dispose HttpResponseMessage with a using like below?
using (HttpResponseMessage response = await client.GetAsync(uri))
{
if (!response.IsSuccessStatusCode)
{
//Do something
}
else
{
//Do something
}
}
Finally my Class looks like as below; Do you see any problem with this?
proxy setting are described in this article
namespace myApp
{
public class HttpService
{
private readonly HttpClient client;
private JsonSerializer _serializer = new JsonSerializer();
public HttpService()
{
if (client == null)
{
try
{
HttpClientHandler handler = new HttpClientHandler
{
Proxy = Xamarin.Forms.DependencyService.Get<IProxyInfoProvider>().GetProxySettings()
};
client = new HttpClient(handler);
}
catch (Exception ex)
{
}
}
}
public async Task<T> GetItemAsync<T>(string url, CancellationToken cancellationToken=default(CancellationToken))
{
T returnObject = default(T);
Uri uri = new Uri(url);
try
{
using (HttpResponseMessage response = await client.GetAsync(uri,cancellationToken))
{
if (!response.IsSuccessStatusCode)
{
//Handle error
}
else
{
returnObject = await getReturnObject<T>(response);
}
}
}
catch (OperationCanceledException)
{
}
catch (System.Net.Http.HttpRequestException)
{
}
catch (Exception ex)
{
}
return returnObject;
}
public async Task<T> getReturnObject<T>(HttpResponseMessage response)
{
T returnObject = default(T);
if (response.IsSuccessStatusCode)
{
using (System.IO.Stream stream = await response.Content.ReadAsStreamAsync())
using (System.IO.StreamReader reader = new System.IO.StreamReader(stream))
using (JsonTextReader json = new JsonTextReader(reader))
{
returnObject = _serializer.Deserialize<T>(json);
}
//string content = await response.Content.ReadAsStringAsync();
//returnObject = JsonConvert.DeserializeObject<T>(content);
}
return returnObject;
}
}
}
xamarin xamarin.forms httpclient asp.net-core-webapi
xamarin xamarin.forms httpclient asp.net-core-webapi
asked Nov 19 at 23:52
batmaci
2,19032849
2,19032849
that should be a static constructor in the second snippet ofHttpService. Both of those snippets basically do the same thing
– Nkosi
Nov 19 at 23:54
@Nkosi so you suggest to change HttpService with static constructor and HttpClient static as well in this case. what will be the advantage and can this cause any memory leak if i use it as static?
– batmaci
Nov 20 at 0:03
I am saying that the example where you say it is correct way to use client is wrong.
– Nkosi
Nov 20 at 0:05
1
The second snippet does not prevent you from creating a second instance of HttpService which will create a second instance of HttpClient. If you want a true singleton. here's a nice in depth article on to do it: csharpindepth.com/Articles/General/Singleton.aspx
– jgoldberger - MSFT
Nov 20 at 0:08
2
A static member will remain in the heap memory for the life of the application. This is not a memory leak as it is always accessible. A memory leak occurs when you have an instantiated object that you no longer have a reference to so that you can no longer use it, access it, or dispose of it, but it is still in memory. So no, you don't have to worry about a memory leak, but the instance will stay in memory until you explicitly dispose it, or until the app is terminated. But you will only ever have the one instance, so not a big worry that it lives for the life of the app.
– jgoldberger - MSFT
Nov 20 at 0:58
|
show 1 more comment
that should be a static constructor in the second snippet ofHttpService. Both of those snippets basically do the same thing
– Nkosi
Nov 19 at 23:54
@Nkosi so you suggest to change HttpService with static constructor and HttpClient static as well in this case. what will be the advantage and can this cause any memory leak if i use it as static?
– batmaci
Nov 20 at 0:03
I am saying that the example where you say it is correct way to use client is wrong.
– Nkosi
Nov 20 at 0:05
1
The second snippet does not prevent you from creating a second instance of HttpService which will create a second instance of HttpClient. If you want a true singleton. here's a nice in depth article on to do it: csharpindepth.com/Articles/General/Singleton.aspx
– jgoldberger - MSFT
Nov 20 at 0:08
2
A static member will remain in the heap memory for the life of the application. This is not a memory leak as it is always accessible. A memory leak occurs when you have an instantiated object that you no longer have a reference to so that you can no longer use it, access it, or dispose of it, but it is still in memory. So no, you don't have to worry about a memory leak, but the instance will stay in memory until you explicitly dispose it, or until the app is terminated. But you will only ever have the one instance, so not a big worry that it lives for the life of the app.
– jgoldberger - MSFT
Nov 20 at 0:58
that should be a static constructor in the second snippet of
HttpService. Both of those snippets basically do the same thing– Nkosi
Nov 19 at 23:54
that should be a static constructor in the second snippet of
HttpService. Both of those snippets basically do the same thing– Nkosi
Nov 19 at 23:54
@Nkosi so you suggest to change HttpService with static constructor and HttpClient static as well in this case. what will be the advantage and can this cause any memory leak if i use it as static?
– batmaci
Nov 20 at 0:03
@Nkosi so you suggest to change HttpService with static constructor and HttpClient static as well in this case. what will be the advantage and can this cause any memory leak if i use it as static?
– batmaci
Nov 20 at 0:03
I am saying that the example where you say it is correct way to use client is wrong.
– Nkosi
Nov 20 at 0:05
I am saying that the example where you say it is correct way to use client is wrong.
– Nkosi
Nov 20 at 0:05
1
1
The second snippet does not prevent you from creating a second instance of HttpService which will create a second instance of HttpClient. If you want a true singleton. here's a nice in depth article on to do it: csharpindepth.com/Articles/General/Singleton.aspx
– jgoldberger - MSFT
Nov 20 at 0:08
The second snippet does not prevent you from creating a second instance of HttpService which will create a second instance of HttpClient. If you want a true singleton. here's a nice in depth article on to do it: csharpindepth.com/Articles/General/Singleton.aspx
– jgoldberger - MSFT
Nov 20 at 0:08
2
2
A static member will remain in the heap memory for the life of the application. This is not a memory leak as it is always accessible. A memory leak occurs when you have an instantiated object that you no longer have a reference to so that you can no longer use it, access it, or dispose of it, but it is still in memory. So no, you don't have to worry about a memory leak, but the instance will stay in memory until you explicitly dispose it, or until the app is terminated. But you will only ever have the one instance, so not a big worry that it lives for the life of the app.
– jgoldberger - MSFT
Nov 20 at 0:58
A static member will remain in the heap memory for the life of the application. This is not a memory leak as it is always accessible. A memory leak occurs when you have an instantiated object that you no longer have a reference to so that you can no longer use it, access it, or dispose of it, but it is still in memory. So no, you don't have to worry about a memory leak, but the instance will stay in memory until you explicitly dispose it, or until the app is terminated. But you will only ever have the one instance, so not a big worry that it lives for the life of the app.
– jgoldberger - MSFT
Nov 20 at 0:58
|
show 1 more comment
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53384307%2fhow-to-implement-httpclient-in-xamarin-forms-applications-using-better-cpu-and-m%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
that should be a static constructor in the second snippet of
HttpService. Both of those snippets basically do the same thing– Nkosi
Nov 19 at 23:54
@Nkosi so you suggest to change HttpService with static constructor and HttpClient static as well in this case. what will be the advantage and can this cause any memory leak if i use it as static?
– batmaci
Nov 20 at 0:03
I am saying that the example where you say it is correct way to use client is wrong.
– Nkosi
Nov 20 at 0:05
1
The second snippet does not prevent you from creating a second instance of HttpService which will create a second instance of HttpClient. If you want a true singleton. here's a nice in depth article on to do it: csharpindepth.com/Articles/General/Singleton.aspx
– jgoldberger - MSFT
Nov 20 at 0:08
2
A static member will remain in the heap memory for the life of the application. This is not a memory leak as it is always accessible. A memory leak occurs when you have an instantiated object that you no longer have a reference to so that you can no longer use it, access it, or dispose of it, but it is still in memory. So no, you don't have to worry about a memory leak, but the instance will stay in memory until you explicitly dispose it, or until the app is terminated. But you will only ever have the one instance, so not a big worry that it lives for the life of the app.
– jgoldberger - MSFT
Nov 20 at 0:58