Description
Describe the bug
Actually the same as #34 witch is closed but not fixed.
Using Refit with Fusillade fails with System.ObjectDisposedException: Cannot access a disposed object. Object name: 'System.Net.Http.HttpConnectionResponseContent'.
The exception is thrown at Refit.RequestBuilderImplementation.d__15`1.MoveNext() in /_/Refit/RequestBuilderImplementation.cs:line 324
It seems that when Fusillade deduplicates requests returning val.Response.ToTask(cancellationToken), Refit fails deserializing HttpContent because it's disposed.
As @clairernovotny on the Refit side with issue #1048 think it looks like a Fusillade bug, I opened the same issue on the Fusillade side.
I don't know if the bug comes from Refit or Fusillade, but I know it throws when using one with each other.
Steps To Reproduce
Create a Refit RestService with any Fusillade's NetCache HttpMessageHandler into the HttpClient, and send the same request at least twice at the same time.
Something dummy like:
try
{
var reqResService = RestService.For<IReqResService>(new HttpClient(NetCache.UserInitiated)
{
BaseAddress = new Uri("https://reqres.in/api")
});
var task1 = reqResService.GetUsersAsync();
var task2 = reqResService.GetUsersAsync();
var result = await Task.WhenAll(task1, task2);
var userList = result.FirstOrDefault();
}
catch (Exception e)
{
throw;
}
with IReqResService:
public interface IReqResService
{
[Get("/users")]
Task<UserList> GetUsersAsync();
}
and Models:
public class UserList
{
[JsonProperty("page")]
public int Page { get; set; }
[JsonProperty("per_page")]
public int PerPage { get; set; }
[JsonProperty("total")]
public int Total { get; set; }
[JsonProperty("total_pages")]
public int TotalPages { get; set; }
[JsonProperty("data")]
public List<User> Data { get; set; }
}
public class User
{
[JsonProperty("id")]
public int Id { get; set; }
[JsonProperty("first_name")]
public string FirstName { get; set; }
[JsonProperty("last_name")]
public string LastName { get; set; }
[JsonProperty("avatar")]
public string Avatar { get; set; }
[JsonProperty("email")]
public string Email { get; set; }
}
Well interface and models are not the point, it's just to illustrate the bug.
Note that everything succeed when using Fusillade without Refit, I mean using HttpClient directly like:
try
{
var client = new HttpClient(NetCache.UserInitiated)
{
BaseAddress = new Uri("https://reqres.in/api/users")
};
var task1 = client.GetAsync("");
var task2 = client.GetAsync("");
var responses = await Task.WhenAll(task1, task2);
var jsonString = await responses.First().Content.ReadAsStringAsync().ConfigureAwait(false);
var userList = JsonConvert.DeserializeObject<UserList>(jsonString);
}
catch (Exception e)
{
throw;
}
Note that everything succeed to, when using Refit without Fusillade like:
try
{
var reqResService = RestService.For<IReqResService>("https://reqres.in/api");
var task1 = reqResService.GetUsersAsync();
var task2 = reqResService.GetUsersAsync();
var result = await Task.WhenAll(task1, task2);
var userList = result.FirstOrDefault();
}
catch (Exception e)
{
throw;
}
So it's only when using both of it.
Expected behavior
Should return result
Environment
- OS: All
- Device: All
- Version: All