public virtual IRevertChangesSavepoint CreateSavepoint(Object source) { if (source == null) { return(null); } List <Object> objList = new List <Object>(); List <IObjRef> objRefs = new List <IObjRef>(); FindAllObjectsToBackup(source, objList, objRefs, new IdentityHashSet <Object>()); IDictionary <Object, RevertChangesSavepoint.IBackup> originalToValueBackup = new IdentityDictionary <Object, RevertChangesSavepoint.IBackup>(); // Iterate manually through the list because the list itself should not be 'backuped' for (int a = objList.Count; a-- > 0;) { BackupObjects(objList[a], originalToValueBackup); } WeakDictionary <Object, RevertChangesSavepoint.IBackup> weakObjectsToBackup = new WeakDictionary <Object, RevertChangesSavepoint.IBackup>(new IdentityEqualityComparer <Object>()); DictionaryExtension.Loop(originalToValueBackup, delegate(Object obj, RevertChangesSavepoint.IBackup backup) { if (backup != null) { weakObjectsToBackup.Add(obj, backup); } }); return(BeanContext.RegisterBean <RevertChangesSavepoint>().PropertyValue("Changes", weakObjectsToBackup).Finish()); }
public virtual void AfterStarted() { // Ensure bean of given name exists in context. An exception will occur on any integrity error Object beanInstance = BeanContext.GetService(BeanName); started = true; if (beanInstance is INotifyPropertyChanged) { BeanContext.Link(new PropertyChangedEventHandler(this.HandlePropertyChangedOfBean)).To(BeanName, INotifyPropertyChangedEvents.PropertyChanged); } if (beanInstance is INotifyCollectionChanged) { BeanContext.Link(new NotifyCollectionChangedEventHandler(this.HandleCollectionChangedOfBean)).To(BeanName, INotifyCollectionChangedEvents.CollectionChanged); } if (pendingPropertiesDict != null) { DictionaryExtension.Loop(pendingPropertiesDict, delegate(String propertyName, Object value) { ((IList <Object>)pendingPropertiesDict[propertyName]).Add(new Object()); RaisePropertyChanged(propertyName); }); } }
protected void AddLiveFirstLevelCaches(IList <IWritableCache> liveChildCaches, bool isTransactionActive) { if (allFLCs.Count == 0) { return; } Thread currentThread = Thread.CurrentThread; DictionaryExtension.Loop(allFLCs, delegate(int cacheId, FlcEntry flcEntry) { CacheFactoryDirective cacheFactoryDirective = flcEntry.GetCacheFactoryDirective(); if (CacheFactoryDirective.NoDCE.Equals(cacheFactoryDirective)) { // This cache is not interested in DCEs at all return; } if (isTransactionActive && CacheFactoryDirective.SubscribeGlobalDCE.Equals(cacheFactoryDirective)) { // This cache is not interested in transactional DCEs return; } IWritableCache childCache = flcEntry.GetFirstLevelCache(); if (childCache == null) { // This cache is not valid any more return; } if (!flcEntry.IsInterestedInThread(currentThread)) { // This cache is bound to a different thread than the current one return; } liveChildCaches.Add(childCache); }); }
public void CollectAllPropertyKeys(ISet <String> allPropertiesSet) { if (Parent != null) { Parent.CollectAllPropertyKeys(allPropertiesSet); } DictionaryExtension.Loop(dictionary, delegate(String key, Object value) { allPropertiesSet.Add(key); }); }
protected IDictionary <ICacheRetriever, IList <IObjRelation> > AssignObjRelsToCacheRetriever(IDictionary <Type, IList <IObjRelation> > sortedIObjRefs) { IDictionary <ICacheRetriever, IList <IObjRelation> > serviceToAssignedObjRefsDict = new IdentityDictionary <ICacheRetriever, IList <IObjRelation> >(); DictionaryExtension.Loop(sortedIObjRefs, delegate(Type type, IList <IObjRelation> objRefs) { ICacheRetriever cacheRetriever = GetRetrieverForType(type); IList <IObjRelation> assignedObjRefs = DictionaryExtension.ValueOrDefault(serviceToAssignedObjRefsDict, cacheRetriever); if (assignedObjRefs == null) { assignedObjRefs = new List <IObjRelation>(); serviceToAssignedObjRefsDict.Add(cacheRetriever, assignedObjRefs); } foreach (IObjRelation objRef in objRefs) { assignedObjRefs.Add(objRef); } }); return(serviceToAssignedObjRefsDict); }
public virtual void AfterStarted(IServiceContext beanContext) { if (Log.InfoEnabled) { IEnumerable <Type> types = FullServiceModelProvider.RegisterKnownTypes(null); #if !SILVERLIGHT SortedList <String, String> sortedTypes = new SortedList <String, String>(); SortedList <String, String> sortedListTypes = new SortedList <String, String>(); foreach (Type type in types) { String name = LogTypesUtil.PrintType(type, true); if (type.IsGenericType) { sortedListTypes.Add(name, name); } else { sortedTypes.Add(name, name); } } Log.Info(sortedTypes.Count + " data types"); Log.Info(sortedListTypes.Count + " collection types"); DictionaryExtension.Loop(sortedTypes, delegate(String key, String value) { Log.Info("Type: " + value); }); DictionaryExtension.Loop(sortedListTypes, delegate(String key, String value) { Log.Info("Type: " + value); }); #else List <String> sortedTypes = new List <String>(); List <String> sortedListTypes = new List <String>(); foreach (Type type in types) { String name = LogTypesUtil.PrintType(type, true); List <String> list; if (type.IsGenericType) { list = sortedListTypes; } else { list = sortedTypes; } bool inserted = false; for (int a = list.Count; a-- > 0;) { String item = list[a]; if (item.CompareTo(name) < 0) { list.Insert(a + 1, name); inserted = true; break; } } if (!inserted) { list.Insert(0, name); } } Log.Info(sortedTypes.Count + " data types"); Log.Info(sortedListTypes.Count + " collection types"); foreach (String value in sortedTypes) { Log.Info("Type: " + value); } foreach (String value in sortedListTypes) { Log.Info("Type: " + value); } #endif } }
public void RemoveObject(IObjRef objRef) { writeLock.Lock(); try { ILoadContainer deletedContainer = refToObjectDict[objRef]; refToObjectDict.Remove(objRef); Type deletedType = objRef.RealType; IEntityMetaData metaData = EntityMetaDataProvider.GetMetaData(deletedType); if (metaData.TypesRelatingToThis.Length == 0) { return; } ISet <Type> typesRelatingToThis = new HashSet <Type>(metaData.TypesRelatingToThis); DictionaryExtension.Loop(refToObjectDict, delegate(IObjRef key, ILoadContainer value) { if (!typesRelatingToThis.Contains(key.RealType)) { // This object does not refer to instances of deleted type } IEntityMetaData typeRelatingMetaData = EntityMetaDataProvider.GetMetaData(key.RealType); RelationMember[] relationMembers = typeRelatingMetaData.RelationMembers; for (int a = relationMembers.Length; a-- > 0;) { RelationMember relationMember = relationMembers[a]; if (!deletedType.Equals(relationMember.ElementType)) { continue; } IObjRef[] relationsOfMember = value.Relations[a]; if (relationsOfMember.Length == 0) { continue; } bool contains = false; for (int b = relationsOfMember.Length; b-- > 0;) { IObjRef relationOfMember = relationsOfMember[b]; if (objRef.Equals(relationOfMember)) { contains = true; break; } } if (!contains) { continue; } if (relationsOfMember.Length == 1) { value.Relations[a] = ObjRef.EMPTY_ARRAY; continue; } List <IObjRef> newRelationsOfMember = new List <IObjRef>(); for (int b = relationsOfMember.Length; b-- > 0;) { IObjRef relationOfMember = relationsOfMember[b]; if (!objRef.Equals(relationOfMember)) { newRelationsOfMember.Add(relationOfMember); } } value.Relations[a] = newRelationsOfMember.ToArray(); } }); } finally { writeLock.Unlock(); } }
public virtual void DataChanged(IDataChange dataChange, DateTime dispatchTime, long sequenceId) { dataChange = dataChange.Derive(InterestedEntityTypes); if (dataChange.IsEmpty) { return; } ISet <Object> directObjectsToDelete = null; ISet <Type> requestedTypes = new HashSet <Type>(); IDictionary <Type, IEntityMetaData> typeToMetaDataDict = new Dictionary <Type, IEntityMetaData>(); GuiThreadHelper.InvokeInGuiAndWait(delegate() { IList <T> entities = Model.Objects; for (int i = entities.Count; i-- > 0;) { Object entity = entities[i]; requestedTypes.Add(entity.GetType()); } }); IList <IDataChangeEntry> dataChangeEntries = dataChange.Inserts; for (int a = dataChangeEntries.Count; a-- > 0;) { requestedTypes.Add(dataChangeEntries[a].EntityType); } dataChangeEntries = dataChange.Updates; for (int a = dataChangeEntries.Count; a-- > 0;) { requestedTypes.Add(dataChangeEntries[a].EntityType); } dataChangeEntries = dataChange.Deletes; for (int a = dataChangeEntries.Count; a-- > 0;) { requestedTypes.Add(dataChangeEntries[a].EntityType); } IList <IEntityMetaData> metaDatas = EntityMetaDataProvider.GetMetaData(ListUtil.ToList(requestedTypes)); foreach (IEntityMetaData metaData in metaDatas) { typeToMetaDataDict[metaData.EntityType] = metaData; } bool consistsOnlyOfDirectDeletes = false; if (dataChange.Deletes.Count > 0) { consistsOnlyOfDirectDeletes = true; foreach (IDataChangeEntry deleteEntry in dataChange.Deletes) { if (deleteEntry is DirectDataChangeEntry) { if (directObjectsToDelete == null) { directObjectsToDelete = new IdentityHashSet <Object>(); } directObjectsToDelete.Add(((DirectDataChangeEntry)deleteEntry).Entry); } else { consistsOnlyOfDirectDeletes = false; } } } IList <T> interestingEntities = null; Object[] contextInformation = GetContextInformation(); IFilterDescriptor filterDescriptor = GetFilterDescriptor(); IList <ISortDescriptor> sortDescriptors = GetSortDescriptors(); IPagingRequest pagingRequest = GetPagingRequest(); IPagingResponse pagingResponse = null; List <IDataChangeEntry> modifiedEntries = new List <IDataChangeEntry>(); modifiedEntries.AddRange(dataChange.All); if (!consistsOnlyOfDirectDeletes) { interestingEntities = CacheContext.ExecuteWithCache(CacheProvider.GetCurrentCache(), delegate() { ConfigureCacheWithEagerLoads(Cache); if (Refresher is IPagingRefresher <T> ) { interestingEntities = new List <T>(); pagingResponse = ((IPagingRefresher <T>)Refresher).Refresh(modifiedEntries, filterDescriptor, sortDescriptors, pagingRequest, contextInformation); foreach (Object obj in pagingResponse.Result) { interestingEntities.Add((T)obj); } return(interestingEntities); } else { if (filterDescriptor != null || sortDescriptors != null) { contextInformation = new Object[2]; contextInformation[0] = filterDescriptor; contextInformation[1] = sortDescriptors; } return(((IRefresher <T>)Refresher).Refresh(modifiedEntries, contextInformation)); } }); } GuiThreadHelper.InvokeInGuiAndWait(delegate() { IList <T> entities = Model.Objects; ISet <T> entitiesToAdd = null; ISet <T> entitiesToRemove = null; IDictionary <T, T> entitiesToReplace = null; IDictionary <IObjRef, T> oldObjRefToOldEntityMap = null; bool mergeModel = false; if (interestingEntities != null && interestingEntities.Count > 0) { entitiesToAdd = new IdentityHashSet <T>(interestingEntities); entitiesToRemove = new IdentityHashSet <T>(entities); entitiesToReplace = new IdentityDictionary <T, T>(); oldObjRefToOldEntityMap = new Dictionary <IObjRef, T>(); mergeModel = true; } for (int i = entities.Count; i-- > 0;) { T oldEntity = entities[i]; if (directObjectsToDelete != null && directObjectsToDelete.Contains(oldEntity)) { if (entitiesToRemove != null) { entitiesToRemove.Remove(oldEntity); } Model.RemoveAt(i); continue; } Type oldEntityType = ProxyHelper.GetRealType(oldEntity.GetType()); PrimitiveMember idMember = typeToMetaDataDict[oldEntityType].IdMember; Object oldEntityId = idMember.GetValue(oldEntity, false); if (oldEntityId == null) { if (entitiesToRemove != null) { entitiesToRemove.Remove(oldEntity); } // Unpersisted object. This object should not be removed // only because of a background DCE continue; } bool entryRemoved = false; foreach (IDataChangeEntry deleteEntry in dataChange.Deletes) { if (deleteEntry is DirectDataChangeEntry) { continue; } Object id = deleteEntry.Id; if (!EqualsItems(oldEntityType, oldEntityId, deleteEntry.EntityType, id)) { continue; } if (entitiesToRemove != null) { entitiesToRemove.Remove(oldEntity); } Model.RemoveAt(i); entryRemoved = true; break; } if (entryRemoved) { continue; } if (mergeModel) { IObjRef oldObjRef = new ObjRef(oldEntityType, ObjRef.PRIMARY_KEY_INDEX, oldEntityId, null); T existingOldEntity = DictionaryExtension.ValueOrDefault(oldObjRefToOldEntityMap, oldObjRef); if (existingOldEntity == null) { oldObjRefToOldEntityMap.Add(oldObjRef, oldEntity); } else if (!Object.ReferenceEquals(existingOldEntity, oldEntity)) { // Force duplicate key exception oldObjRefToOldEntityMap.Add(oldObjRef, oldEntity); } } } if (oldObjRefToOldEntityMap != null && oldObjRefToOldEntityMap.Count > 0) { IDictionary <IObjRef, T> newObjRefToNewEntityMap = new Dictionary <IObjRef, T>(); for (int a = interestingEntities.Count; a-- > 0;) { T newEntity = interestingEntities[a]; Type newEntityType = ProxyHelper.GetRealType(newEntity.GetType()); PrimitiveMember idMember = typeToMetaDataDict[newEntityType].IdMember; Object newEntityId = idMember.GetValue(newEntity, false); IObjRef newObjRef = new ObjRef(newEntityType, ObjRef.PRIMARY_KEY_INDEX, newEntityId, null); newObjRefToNewEntityMap.Add(newObjRef, newEntity); } DictionaryExtension.Loop(oldObjRefToOldEntityMap, delegate(IObjRef objRef, T oldEntity) { T newEntity = DictionaryExtension.ValueOrDefault(newObjRefToNewEntityMap, objRef); if (newEntity == null) { // Nothing to do if current oldEntity has no corresponding newEntity return; } entitiesToAdd.Remove(newEntity); if (!Object.ReferenceEquals(oldEntity, newEntity) && (dataChange.IsLocalSource || !(oldEntity is IDataObject) || !((IDataObject)oldEntity).ToBeUpdated)) { entitiesToReplace[oldEntity] = newEntity; } entitiesToRemove.Remove(oldEntity); }); } if (mergeModel) { for (int a = entities.Count; a-- > 0;) { T item = entities[a]; if (entitiesToRemove.Contains(item)) { Model.RemoveAt(a); continue; } T replacingItem = DictionaryExtension.ValueOrDefault(entitiesToReplace, item); if (replacingItem != null) { Model.Replace(a, replacingItem); continue; } } IEnumerator <T> enumerator = entitiesToAdd.GetEnumerator(); while (enumerator.MoveNext()) { T entityToAdd = enumerator.Current; Model.Add(entityToAdd); } if (hasPagedViewModel) { UpdatePagingInformation(pagingResponse); } UpdateAfterDCE(); } }); }
private void Application_Startup(object sender, StartupEventArgs e) { String configFolder = "config"; String fileName = "Minerva.properties"; String filePath = configFolder + "\\" + fileName; IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForSite(); Stream primaryPropertyStream = null; try { storage.CreateDirectory("config"); primaryPropertyStream = new IsolatedStorageFileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite, storage); } catch (IsolatedStorageException) { // Intended blank } catch (FileNotFoundException) { // Intended blank } String urlString = "/Minerva.Client;component/" + filePath; StreamResourceInfo streamResourceInfo = Application.GetResourceStream(new Uri(urlString, UriKind.Relative)); if (streamResourceInfo == null) { #if DEVELOP urlString = "/Minerva.Client;component/" + configFolder + "/Osthus.properties"; #else urlString = "/Minerva.Client;component/" + configFolder + "/Osthus_Production.properties"; #endif streamResourceInfo = Application.GetResourceStream(new Uri(urlString, UriKind.Relative)); } Properties properties = Properties.Application; if (streamResourceInfo != null) { properties.Load(streamResourceInfo.Stream); } String servicePort = DictionaryExtension.ValueOrDefault(e.InitParams, "serviceport"); String serviceHost = DictionaryExtension.ValueOrDefault(e.InitParams, "servicehost"); DictionaryExtension.Loop(e.InitParams, delegate(String key, String value) { properties.Set(key, value); }); if (servicePort != null) { properties[ServiceConfigurationConstants.ServiceHostPort] = servicePort; } if (serviceHost != null) { properties[ServiceConfigurationConstants.ServiceHostName] = serviceHost; } properties.Load(primaryPropertyStream); Properties.System[ServiceWCFConfigurationConstants.TransferObjectsScope] = ".+"; Properties.System[EventConfigurationConstants.PollingActive] = "true"; Properties.System[ServiceConfigurationConstants.NetworkClientMode] = "true"; Properties.System[ServiceConfigurationConstants.GenericTransferMapping] = "false"; Properties.System[ServiceConfigurationConstants.IndependentMetaData] = "false"; properties[ServiceConfigurationConstants.ServiceBaseUrl] = "${" + ServiceConfigurationConstants.ServiceProtocol + "}://" + "${" + ServiceConfigurationConstants.ServiceHostName + "}" + ":" + "${" + ServiceConfigurationConstants.ServiceHostPort + "}" + "${" + ServiceConfigurationConstants.ServicePrefix + "}"; properties[ServiceConfigurationConstants.ServiceProtocol] = "http"; properties[ServiceConfigurationConstants.ServiceHostName] = "localhost."; properties[ServiceConfigurationConstants.ServiceHostPort] = "9080"; properties[ServiceConfigurationConstants.ServicePrefix] = "/helloworld"; LoggerFactory.LoggerType = typeof(De.Osthus.Ambeth.Log.ClientLogger); Log = LoggerFactory.GetLogger(typeof(App), properties); if (Log.InfoEnabled) { ISet <String> allPropertiesSet = properties.CollectAllPropertyKeys(); List <String> allPropertiesList = new List <String>(allPropertiesSet); allPropertiesList.Sort(); Log.Info("Property environment:"); foreach (String property in allPropertiesList) { Log.Info("Property " + property + "=" + properties[property]); } } Type type = storage.GetType(); PropertyInfo propertyInfo = null; while (type != null) { propertyInfo = type.GetProperty("RootDirectory", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public); if (propertyInfo != null) { break; } type = type.BaseType; } AssemblyHelper.RegisterAssemblyFromType(typeof(BytecodeModule)); AssemblyHelper.RegisterAssemblyFromType(typeof(CacheBootstrapModule)); AssemblyHelper.RegisterAssemblyFromType(typeof(CacheBytecodeModule)); AssemblyHelper.RegisterAssemblyFromType(typeof(CacheDataChangeBootstrapModule)); AssemblyHelper.RegisterAssemblyFromType(typeof(DataChangeBootstrapModule)); AssemblyHelper.RegisterAssemblyFromType(typeof(EventBootstrapModule)); AssemblyHelper.RegisterAssemblyFromType(typeof(IocBootstrapModule)); AssemblyHelper.RegisterAssemblyFromType(typeof(MergeBootstrapModule)); AssemblyHelper.RegisterAssemblyFromType(typeof(CompositeIdModule)); AssemblyHelper.RegisterAssemblyFromType(typeof(PrivilegeBootstrapModule)); AssemblyHelper.RegisterAssemblyFromType(typeof(SecurityBootstrapModule)); AssemblyHelper.RegisterAssemblyFromType(typeof(ServiceBootstrapModule)); AssemblyHelper.RegisterAssemblyFromType(typeof(MethodDescription)); AssemblyHelper.RegisterAssemblyFromType(typeof(MinervaCoreBootstrapModule)); AssemblyHelper.RegisterAssemblyFromType(typeof(RESTBootstrapModule)); AssemblyHelper.RegisterAssemblyFromType(typeof(XmlBootstrapModule)); AssemblyHelper.RegisterAssemblyFromType(typeof(FilterDescriptor)); AssemblyHelper.RegisterAssemblyFromType(typeof(HelloWorldModule)); AssemblyHelper.InitAssemblies("ambeth\\..+", "minerva\\..+"); properties[XmlConfigurationConstants.PackageScanPatterns] = @"De\.Osthus(?:\.Ambeth|\.Minerva)(?:\.[^\.]+)*(?:\.Transfer|\.Model|\.Service)\..+"; properties[CacheConfigurationConstants.FirstLevelCacheType] = "SINGLETON"; properties[CacheConfigurationConstants.OverwriteToManyRelationsInChildCache] = "false"; properties[CacheConfigurationConstants.UpdateChildCache] = "true"; properties[MinervaCoreConfigurationConstants.EntityProxyActive] = "true"; properties[ServiceConfigurationConstants.TypeInfoProviderType] = typeof(MergeTypeInfoProvider).FullName; // Set this to false, to test with mocks (offline) bool Online = true; properties[CacheConfigurationConstants.CacheServiceBeanActive] = Online.ToString(); properties[EventConfigurationConstants.EventServiceBeanActive] = Online.ToString(); properties[MergeConfigurationConstants.MergeServiceBeanActive] = Online.ToString(); properties[SecurityConfigurationConstants.SecurityServiceBeanActive] = Online.ToString(); properties[HelloWorldConfigurationConstants.HelloWorldServiceBeanActive] = Online.ToString(); properties[MergeConfigurationConstants.MergeServiceMockType] = typeof(HelloWorldMergeMock).FullName; //already default: properties[RESTConfigurationConstants.HttpAcceptEncodingZipped] = "true"; //already default: properties[RESTConfigurationConstants.HttpContentEncodingZipped] = "true"; //already default: properties[RESTConfigurationConstants.HttpUseClient] = "true"; IServiceContext bootstrapContext = BeanContextFactory.CreateBootstrap(properties); try { // Create child context and override root context BeanContext = bootstrapContext.CreateService(delegate(IBeanContextFactory bcf) { bcf.RegisterAnonymousBean <MainPageModule>(); bcf.RegisterAnonymousBean(typeof(HelloWorldModule)); AssemblyHelper.HandleTypesFromCurrentDomainWithAnnotation <FrameworkModuleAttribute>(delegate(Type bootstrapModuleType) { //if (!typeof(IInitializingBootstrapMockModule).IsAssignableFrom(bootstrapModuleType)) { if (Log.InfoEnabled) { Log.Info("Autoresolving bootstrap module: '" + bootstrapModuleType.FullName + "'"); } bcf.RegisterAnonymousBean(bootstrapModuleType); } }); bcf.RegisterExternalBean("app", this); }, typeof(RESTBootstrapModule)); FlattenHierarchyProxy.Context = BeanContext; BeanContext.GetService <IThreadPool>().Queue(delegate() { double result = BeanContext.GetService <IHelloWorldService>().DoFunnyThings(5, "hallo"); double result2 = BeanContext.GetService <IHelloWorldService>().DoFunnyThings(6, "hallo"); if (Math.Abs(result - result2) != 1) { throw new Exception("Process execution failed with unexpected result value: " + result + "/" + result2); } Log.Info("" + result); //Type enhancedType = BeanContext.GetService<IBytecodeEnhancer>().GetEnhancedType(typeof(TestEntity), EntityEnhancementHint.HOOK); //TestEntity instance = (TestEntity)Activator.CreateInstance(enhancedType); //instance.Id = 1; //IEntityMetaData metaData = BeanContext.GetService<IEntityMetaDataProvider>().GetMetaData(enhancedType); //IObjRelation result3 = ((IValueHolderContainer)instance).GetSelf("Relation"); //Object targetCache = ((IValueHolderContainer)instance).TargetCache; //((IValueHolderContainer)instance).TargetCache = new ChildCache(); //Console.WriteLine("TestT"); }); SynchronizationContext syncContext = BeanContext.GetService <SynchronizationContext>(); syncContext.Post((object state) => { RootVisual = BeanContext.GetService <UIElement>("mainPage"); }, null); } catch (Exception ex) { if (Log.ErrorEnabled) { Log.Error(ex); } throw; } }
protected void GetData <V, R>(IDictionary <ICacheRetriever, IList <V> > assignedArguments, IList <R> result, GetDataDelegate <V, R> getDataDelegate) { if (ThreadPool == null || assignedArguments.Count == 1) { // Serialize GetEntities() requests DictionaryExtension.Loop(assignedArguments, delegate(ICacheRetriever cacheRetriever, IList <V> arguments) { IList <R> partResult = getDataDelegate.Invoke(cacheRetriever, arguments); foreach (R partItem in partResult) { result.Add(partItem); } }); return; } int remainingResponses = assignedArguments.Count; Exception routedException = null; // Execute CacheRetrievers in parallel DictionaryExtension.Loop(assignedArguments, delegate(ICacheRetriever cacheRetriever, IList <V> arguments) { ThreadPool.Queue(delegate() { try { IList <R> partResult = getDataDelegate.Invoke(cacheRetriever, arguments); lock (result) { foreach (R partItem in partResult) { result.Add(partItem); } } } catch (Exception e) { routedException = e; } finally { lock (result) { remainingResponses--; Monitor.Pulse(result); } } }); }); lock (result) { while (remainingResponses > 0 && routedException == null) { Monitor.Wait(result); } } if (routedException != null) { throw new Exception("Error occured while retrieving entities", routedException); } }