/// <summary> /// Startup the resource pool /// </summary> public async Task <bool> StartupAsync(Func <Task <T> > createConnectionHandler, Func <T, Task> closeConnectionHandler) { await ShutdownAsync(); IsRunning = true; this.createResourceHandler = createConnectionHandler; this.closeResourceHandler = closeConnectionHandler; requestQueue = new List <Request>(); resourcePool = new List <ResourcePoolEntry>(); //Initialize the worker which will increase/decrease the pool size as necessary resourcePoolMonitor = new AutoResetWorker() { PeriodicSignallingTime = TimeSpan.FromSeconds(1) //May need to re-evaluate this interval }; if (!await resourcePoolMonitor.StartupAsync(connectionPoolMonitor_DoWork, null, () => IsRunning)) { await ShutdownAsync(); return(false); } resourcePoolInitializing = true; resourcePoolMonitor.Set(); return(true); }
/// <summary> /// Shutdown resource pool /// </summary> public async Task ShutdownAsync(int maxWait = -1) { IsRunning = false; if (resourcePoolMonitor != null) { await resourcePoolMonitor.ShutdownAsync(); resourcePoolMonitor = null; } //Close any lingering pool connections DateTime timeoutTime = maxWait >= 0 ? DateTime.MaxValue : DateTime.Now.AddMilliseconds(maxWait); while (resourcePool.Count > 0) { var shutdownTasks = new List <Task>(); bool timeoutExpired = DateTime.Now < timeoutTime; int index = 0; while (index < resourcePool.Count) { var resource = resourcePool[index]; if (resource.InUse && !timeoutExpired) { //Give in-use resources time to finish their work before we close their connection index++; } else { resourcePool.RemoveAt(index); shutdownTasks.Add(closeResourceHandler(resource.Connection)); } } if (shutdownTasks.Count > 0) { await Task.WhenAll(shutdownTasks.ToArray()); } else { await Task.Delay(10); } } createResourceHandler = null; closeResourceHandler = null; requestQueue = null; resourcePool = null; }