Mah*_*Ali 7 .net c# xamarin.android async-await dotnet-httpclient
我正在使用Xamarin(Android)构建应用程序,它使用PCL项目作为服务层.我有一个Web Api端点,我正在使用HttpClient它.
一切正常,但是如果我让我的Android应用程序打开并闲置一段时间(比如2分钟)并且我尝试发出新请求,那么使用单例的第一个请求HttpClient将无效.它永远不会返回并保持在那里直到超时(TaskCancelledException).我也在我的Api上设置了一个断点,它没有被击中.如果我再次尝试发送请求,那么它可以工作.
经过大量的调试后,我发现只有当我尝试使用HttpClient单例作为单例时才会发生这种情况.如果我HttpClient为每个请求创建一个新的一切都有效.
起初我认为这是一个僵局问题,我做了很多研究,并按照其他答案和Stephen Cleary的优秀帖子所描述的指导原则进行了双重检查,我几乎可以肯定事实并非如此.
我正在使用ConfigureAwait(false)来自我的PCL项目的每次调用,因此它不会捕获上下文.
在Android片段内:
SampleService svc = new SampleService();
response = await svc.GetAllSamples();
Run Code Online (Sandbox Code Playgroud)
这个服务叫(在我的PCL项目中):
public class SampleService
{
public HttpClient Client { get; set; }
public SampleService()
{
// resolves my singleton instance and uses my custom DelegatingHandler
Client = CustomHttpClient.Instance;
}
public async Task<IEnumerable<Sample>> GetAllSamples()
{
IEnumerable<Sample> list = null;
// this never returns and timeouts the first time
using (var response = await Client.GetAsync("samples").ConfigureAwait(false))
{
if (response.IsSuccessStatusCode)
{
string json = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
lista = await Task.Run(() => JsonConvert.DeserializeObject<IEnumerable<Sample>>(json)).ConfigureAwait(false);
}
return list;
}
}
}
Run Code Online (Sandbox Code Playgroud)
这就是我构建Singleton实例的方法:
public sealed class CustomHttpClient
{
private static HttpClient _client;
public static HttpClient GetClient()
{
if (_client == null)
{
HttpMessageHandler messageHandler = new HttpClientHandler();
_client = new HttpClient(messageHandler);
_client.Timeout = TimeSpan.FromSeconds(30);
_client.BaseAddress = new Uri("myendpoint");
_client.DefaultRequestHeaders.Accept.Clear();
_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}
return _client;
}
}
Run Code Online (Sandbox Code Playgroud)
我试图在这里简化和隔离代码,如果我可以提供任何其他有用的代码片段,请告诉我.
对于HttpClient我不知道的单身人士,我做错了吗?
更新:为了澄清,我试图使用HttpClientSingleton只是因为,正如我在Darrel Miller的回答中和在使用ASP.NET设计可演化的Web API(第14章)一书中所发现的那样,它们被设计为可重用的和线程安全(在大多数情况下).根据我的研究,我没有使用任何非线程安全的东西.
| 归档时间: |
|
| 查看次数: |
1830 次 |
| 最近记录: |