reactiveui/Fusillade

Refit + Fusillade fails with System.ObjectDisposedException: Cannot access a disposed objec

vasiliy-s opened this issue · 2 comments

I have a xamarin forms project. I hoped to use both Refit and Fusillade for it.
When i use either of them everything works fine but when i start to use them together then requests fails.

Fusillade 1.0.0
Xamarin.Forms 3.0.0.296286
Refit 4.3.0

**Single ** request works fine. Fails only when Fusillade deduplicates queries.

The code is simple. I got an empty ContentPage with button and label.
The button click handler contains code:

var api = RestService.For<IScheduleApi>(
	new HttpClient( NetCache.UserInitiated )
	{
		BaseAddress = new Uri( Config.ApiUrl )
	} );
			
var result = await api.GetText();
this.TextLabel.Text = result;

IScheduleApi is the following:

[Headers("Accept: application/json")]
    public interface IScheduleApi
	{
		[Get("/schedule")]
		Task<string> GetText();
	}

The web service just sleeps and returns text:

Thread.Sleep(4000);
return "Text";

When i click on button and wait then i get the response and everything is fine.
When i click next time and again wait - everything works.
But if i do more that one click then i get the exeption. Though i am not sure which one of the libraries causes it

04-03 19:18:50.144 I/MonoDroid(10742): UNHANDLED EXCEPTION:
04-03 19:18:50.174 I/MonoDroid(10742): System.ObjectDisposedException: Cannot access a disposed object.
04-03 19:18:50.174 I/MonoDroid(10742): Object name: 'System.Net.Http.StreamContent'.
04-03 19:18:50.174 I/MonoDroid(10742): at System.Net.Http.HttpContent+d__18.MoveNext () [0x00027] in :0
04-03 19:18:50.174 I/MonoDroid(10742): --- End of stack trace from previous location where exception was thrown ---
04-03 19:18:50.174 I/MonoDroid(10742): at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in :0
04-03 19:18:50.174 I/MonoDroid(10742): at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003e] in :0
04-03 19:18:50.174 I/MonoDroid(10742): at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in :0
04-03 19:18:50.174 I/MonoDroid(10742): at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in :0
04-03 19:18:50.174 I/MonoDroid(10742): at System.Runtime.CompilerServices.ConfiguredTaskAwaitable1+ConfiguredTaskAwaiter[TResult].GetResult () [0x00000] in <fcbf47a04b2e4d90beafbae627e1fca4>:0 04-03 19:18:50.174 I/MonoDroid(10742): at Refit.RequestBuilderImplementation+<>c__DisplayClass11_01+<b__0>d[T].MoveNext () [0x003d2] in :0
04-03 19:18:50.174 I/MonoDroid(10742): --- End of stack trace from previous location where exception was thrown ---
04-03 19:18:50.174 I/MonoDroid(10742): at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in :0
04-03 19:18:50.174 I/MonoDroid(10742): at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003e] in :0
04-03 19:18:50.174 I/MonoDroid(10742): at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in :0
04-03 19:18:50.174 I/MonoDroid(10742): at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in :0
04-03 19:18:50.174 I/MonoDroid(10742): at System.Runtime.CompilerServices.TaskAwaiter`1[TResult].GetResult () [0x00000] in :0
04-03 19:18:50.174 I/MonoDroid(10742): at TempStaff.SchedulePage+d__3.MoveNext () [0x00051] in D:\Code\Avilum\tempstaff\TempStaff\TempStaff\SchedulePage.xaml.cs:69
04-03 19:18:50.174 I/MonoDroid(10742): --- End of stack trace from previous location where exception was thrown ---
04-03 19:18:50.174 I/MonoDroid(10742): at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in :0
04-03 19:18:50.174 I/MonoDroid(10742): at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.b__6_0 (System.Object state) [0x00000] in :0
04-03 19:18:50.174 I/MonoDroid(10742): at Android.App.SyncContext+<>c__DisplayClass2_0.b__0 () [0x00000] in <551e90b840814b76a3d15b7bbaa8a77c>:0
04-03 19:18:50.174 I/MonoDroid(10742): at Java.Lang.Thread+RunnableImplementor.Run () [0x00008] in <551e90b840814b76a3d15b7bbaa8a77c>:0
04-03 19:18:50.174 I/MonoDroid(10742): at Java.Lang.IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr native__this) [0x00008] in <551e90b840814b76a3d15b7bbaa8a77c>:0
04-03 19:18:50.174 I/MonoDroid(10742): at (wrapper dynamic-method) System.Object.aa6e990f-8152-4823-ae62-44e7a273b201(intptr,intptr)

So accidentally realized that the issue is in disposing of HttpClient.

So this works fine.

var client = new HttpClient( NetCache.Background )
{
	BaseAddress = new Uri( Config.ApiUrl )
};

var response = await client.GetAsync( "schedule" ).ConfigureAwait(false);
var jsonString = await response.Content.ReadAsStringAsync().ConfigureAwait( false );
return JsonConvert.DeserializeObject<ApiResult<IList<ScheduleEntry>>>(jsonString);

But if i wrap it in using:

using(var client = new HttpClient( NetCache.Background )){..}

The all requests except the first one fails

Yeah usually most people recommend not disposing of a HttpClient, numerous examples around the stackoverflow over that one. Closing this one.