using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading.Tasks;
class HttpClient : IDisposable
public async Task<object> GetAsync(string url)
class Gateway : IDisposable
protected readonly HttpClient _client = new HttpClient();
protected bool _disposalRequested = false;
protected bool _disposalCompleted = false;
protected int _tasksRunning = 0;
Console.WriteLine("Dispose() called.");
_disposalRequested = true;
Console.WriteLine("No running tasks, so disposing immediately.");
Console.WriteLine("There are running tasks, so disposal shall be deferred.");
protected void DisposeInternal()
Console.WriteLine("Disposing");
_disposalCompleted = true;
protected async Task<T> AddDisposeWrapper<T>(Func<Task<T>> func)
if (_disposalRequested) throw new ObjectDisposedException("Disposal has already been requested. No new requests can be handled at this point.");
var result = await func();
protected async Task DisposalCheck()
if (_disposalRequested) DisposeInternal();
public Task<Data> Request1()
public Task<Data> Request2()
protected async Task<Data> Request1Internal()
Console.WriteLine("Performing Request1 (slow)");
Console.WriteLine("Request1 has finished. Returning new Data.");
protected async Task<Data> Request2Internal()
Console.WriteLine("Performing Request2 (fast)");
Console.WriteLine("Request2 has finished. Returning new Data.");
public static async Task Test1()
using (var gateway = new Gateway())
task = gateway.Request1();
Console.WriteLine("Test 1 is complete.");
public static async Task Test2()
using (var gateway = new Gateway())
task = gateway.Request2();
Console.WriteLine("Test 2 is complete.");
public static async Task MainAsync()
public static void Main()
MainAsync().GetAwaiter().GetResult();
Console.WriteLine("Run completed at {0:yyyy-MM-dd HH:mm:ss}", DateTime.Now);