public ResourceInfo(ResourceNode resourceNode) { ResourceNode = resourceNode; }
/// <summary> /// Blocks the thread while closing all resources in parallel. /// </summary> private void CloseAllResources() { Dictionary <IResource, List <IResource> > dependencies = openedResources.ToDictionary(r => r.Resource, r => new List <IResource>()); // this dictionary will hold resources with dependencies (keys) and what resources depend on them (values) foreach (var n in openedResources) { foreach (var dep in n.StrongDependencies) { dependencies[dep].Add(n.Resource); } } Dictionary <IResource, Task> closeTasks = new Dictionary <IResource, Task>(); foreach (var r in openedResources) { closeTasks[r.Resource] = new Task(o => { ResourceNode res = (ResourceNode)o; // Wait for the resource to open to open before closing it. // in rare cases, another instrument failing open will cause close to be called. try { openTasks[res.Resource].Wait(); } catch { } // wait for resources that depend on this resource (res) to close before closing this Task.WaitAll(dependencies[res.Resource].Select(x => closeTasks[x]).ToArray()); var reslog = GetLogSource(res.Resource); Stopwatch timer = Stopwatch.StartNew(); try { res.Resource.Close(); } catch (Exception e) { log.Error("Error while closing \"{0}\": {1}", res.Resource.Name, e.Message); log.Debug(e); } if (reslog != null) { reslog.Info(timer, "Resource \"{0}\" closed.", res.Resource); } }, r); } closeTasks.Values.ToList().ForEach(t => t.Start()); void complainAboutWait() { log.Debug("Waiting for resources to close:"); foreach (var res in openTasks.Keys) { if (res.IsConnected) { log.Debug(" - {0}", res); } } } using (TimeoutOperation.Create(complainAboutWait)) Task.WaitAll(closeTasks.Values.ToArray()); }