//static int count = 10000000; ////[TestInitialize] //public void InitManually() //{ // base.InitManually(GetType()); //} //static Object[] objects; //static ValueHolderContainerTest() //{ // objects = new Object[count]; // for (int a = count; a-- > 0; ) // { // objects[a] = new Object(); // } //} //[TestMethod] //public void test_Dictionary() //{ // Dictionary<Object, Object> dict = new Dictionary<Object, Object>(count, new IdentityEqualityComparer<Object>()); // //for (int a = count; a-- > 0; ) // //{ // // dict.Add(a, objects[a]); // // dict.Remove(a); // // dict.Add(a, objects[a]); // // dict.Remove(a); // // dict.Add(a, objects[a]); // // dict.Remove(a); // // dict.Add(a, objects[a]); // // dict.Remove(a); // // dict.Add(a, objects[a]); // // dict.Remove(a); // //} // for (int a = count; a-- > 0; ) // { // dict.Add(a, objects[a]); // } // for (int a = 10; a-- > 0; ) // { // foreach (KeyValuePair<Object, Object> entry in dict) // { // Object key = entry.Key; // Object value = entry.Value; // if (!Object.ReferenceEquals(objects[(int)key], value)) // { // throw new Exception(); // } // } // } //} //[TestMethod] //public void test_HashMap() //{ // IdentityLinkedMap<Object, Object> dict = IdentityLinkedMap<Object, Object>.Create(count); // //for (int a = count; a-- > 0; ) // //{ // // dict.Put(a, objects[a]); // // dict.Remove(a); // // dict.Put(a, objects[a]); // // dict.Remove(a); // // dict.Put(a, objects[a]); // // dict.Remove(a); // // dict.Put(a, objects[a]); // // dict.Remove(a); // // dict.Put(a, objects[a]); // // dict.Remove(a); // //} // for (int a = count; a-- > 0; ) // { // dict.Put(a, objects[a]); // } // for (int a = 10; a-- > 0; ) // { // foreach (Entry<Object, Object> entry in dict) // { // Object key = entry.Key; // Object value = entry.Value; // if (!Object.ReferenceEquals(objects[(int)key], value)) // { // throw new Exception(); // } // } // } //} //[TestMethod] //public void test_PropertyInfo() //{ // Material mat = new Material(); // PropertyInfo pi = mat.GetType().GetProperty("Name"); // DateTime prePi = DateTime.Now; // for (int a = count; a-- > 0; ) // { // Object piValue = pi.GetValue(mat, null); // piValue = pi.GetValue(mat, null); // piValue = pi.GetValue(mat, null); // piValue = pi.GetValue(mat, null); // piValue = pi.GetValue(mat, null); // piValue = pi.GetValue(mat, null); // piValue = pi.GetValue(mat, null); // piValue = pi.GetValue(mat, null); // piValue = pi.GetValue(mat, null); // piValue = pi.GetValue(mat, null); // piValue = pi.GetValue(mat, null); // piValue = pi.GetValue(mat, null); // piValue = pi.GetValue(mat, null); // piValue = pi.GetValue(mat, null); // piValue = pi.GetValue(mat, null); // piValue = pi.GetValue(mat, null); // piValue = pi.GetValue(mat, null); // piValue = pi.GetValue(mat, null); // piValue = pi.GetValue(mat, null); // piValue = pi.GetValue(mat, null); // } // DateTime postPi = DateTime.Now; // long piTime = postPi.Ticks - prePi.Ticks; // Console.WriteLine(piTime); //} //[TestMethod] //public void test_GetDelegate() //{ // Material mat = new Material(); // MemberGetDelegate del = TypeUtility.GetMemberGetDelegate(mat.GetType(), "Name"); // MemberSetDelegate setDel = TypeUtility.GetMemberSetDelegate(mat.GetType(), "Id"); // setDel(mat, 5); // DateTime preDel = DateTime.Now; // for (int a = count; a-- > 0; ) // { // Object delValue = del(mat); // delValue = del(mat); // delValue = del(mat); // delValue = del(mat); // delValue = del(mat); // delValue = del(mat); // delValue = del(mat); // delValue = del(mat); // delValue = del(mat); // delValue = del(mat); // delValue = del(mat); // delValue = del(mat); // delValue = del(mat); // delValue = del(mat); // delValue = del(mat); // delValue = del(mat); // delValue = del(mat); // delValue = del(mat); // delValue = del(mat); // delValue = del(mat); // } // DateTime postDel = DateTime.Now; // long delTime = postDel.Ticks - preDel.Ticks; // Console.WriteLine(delTime); //} protected void WaitForUI() { GuiThreadHelper.InvokeInGuiAndWait(delegate() { // Intended blank }); }
protected void ChangeFirstLevelCaches(CacheDependencyNode node, ISet <IObjRef> intermediateDeletes) { List <IDataChangeEntry> deletes = new List <IDataChangeEntry>(); ICacheModification cacheModification = this.CacheModification; bool oldCacheModificationValue = cacheModification.Active; if (!oldCacheModificationValue) { cacheModification.Active = true; } try { ChangeFirstLevelCachesIntern(node, intermediateDeletes); } finally { if (!oldCacheModificationValue) { cacheModification.Active = oldCacheModificationValue; } } if (deletes.Count > 0) { IDataChange dce = DataChangeEvent.Create(0, 0, deletes.Count); ListUtil.AddAll(dce.Deletes, dce.Deletes.Count, deletes); GuiThreadHelper.InvokeOutOfGui(delegate() { EventDispatcher.DispatchEvent(dce); }); } }
protected void MergePhase2(Object objectToMerge, Object objectToDelete, MergeHandle mergeHandle, ICUDResult cudResult, ProceedWithMergeHook proceedHook, MergeFinishedCallback mergeFinishedCallback, bool addNewEntitiesToCache) { List <Object> unpersistedObjectsToDelete = new List <Object>(); RemoveUnpersistedDeletedObjectsFromCudResult(cudResult.AllChanges, cudResult.GetOriginalRefs(), unpersistedObjectsToDelete); if (objectToDelete != null) { IList <IObjRef> oriList = OriHelper.ExtractObjRefList(objectToDelete, mergeHandle); AppendDeleteContainers(objectToDelete, oriList, cudResult.AllChanges, cudResult.GetOriginalRefs(), unpersistedObjectsToDelete); } // Store the MergeFinishedCallback from this thread on the stack and set the property null (for following calls): if (GuiThreadHelper.IsInGuiThread()) { GuiThreadHelper.InvokeOutOfGui(delegate() { MergePhase3(objectToMerge, unpersistedObjectsToDelete, cudResult, proceedHook, mergeFinishedCallback, addNewEntitiesToCache); }); } else { MergePhase3(objectToMerge, unpersistedObjectsToDelete, cudResult, proceedHook, mergeFinishedCallback, addNewEntitiesToCache); } }
protected void FireQueuedPropertyChangeEvents() { List <IBackgroundWorkerDelegate> queuedEvents = queuedEventsTL.Value; if (queuedEvents == null) { return; } queuedEventsTL.Value = null; Log.Info("ICacheModification.FlushInGui()"); GuiThreadHelper.InvokeInGui(delegate() { Log.Info("ICacheModification.FlushWithinGui()"); try { for (int a = 0, size = queuedEvents.Count; a < size; a++) { IBackgroundWorkerDelegate queuedEvent = queuedEvents[a]; queuedEvent(); } } catch (Exception e) { Log.Error(e); throw; } Log.Info("ICacheModification.FlushWithinGui finished"); }); }
protected void MergePhase1(Object objectToMerge, Object objectToDelete, ProceedWithMergeHook proceedHook, MergeFinishedCallback mergeFinishedCallback, bool addNewEntitiesToCache) { ICUDResult cudResult; MergeHandle mergeHandle; IDisposableCache childCache = CacheFactory.Create(CacheFactoryDirective.NoDCE, false, false, "MergeProcess.ORIGINAL"); try { mergeHandle = BeanContext.RegisterBean <MergeHandle>() // .PropertyValue("Cache", childCache) // .Finish(); cudResult = MergeController.MergeDeep(objectToMerge, mergeHandle); mergeHandle.Cache = null; } finally { childCache.Dispose(); childCache = null; } if (GuiThreadHelper.IsInGuiThread()) { MergePhase2(objectToMerge, objectToDelete, mergeHandle, cudResult, proceedHook, mergeFinishedCallback, addNewEntitiesToCache); } else { GuiThreadHelper.InvokeInGui(delegate() { MergePhase2(objectToMerge, objectToDelete, mergeHandle, cudResult, proceedHook, mergeFinishedCallback, addNewEntitiesToCache); }); } }
protected virtual void RaisePropertyChanged(String propertyName) { GuiThreadHelper.InvokeInGui(delegate() { var localEventHandler = PropertyChanged; if (localEventHandler != null) { localEventHandler.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }); }
public void ApplyChangesToOriginals(ICUDResult cudResult, IOriCollection oriCollection, ICache cache) { if (GuiThreadHelper.IsInGuiThread()) { ApplyChangesToOriginalsIntern(cudResult, oriCollection, cache); return; } GuiThreadHelper.InvokeInGuiAndWait(new IBackgroundWorkerDelegate(delegate() { ApplyChangesToOriginalsIntern(cudResult, oriCollection, cache); })); }
public void Process(Object objectToMerge, Object objectToDelete, ProceedWithMergeHook proceedHook, MergeFinishedCallback mergeFinishedCallback, bool addNewEntitiesToCache) { if (GuiThreadHelper.IsInGuiThread()) { GuiThreadHelper.InvokeOutOfGui(delegate() { MergePhase1(objectToMerge, objectToDelete, proceedHook, mergeFinishedCallback, addNewEntitiesToCache); }); } else { MergePhase1(objectToMerge, objectToDelete, proceedHook, mergeFinishedCallback, addNewEntitiesToCache); } }
public virtual void Populate() { var localRequest = new Object(); lock (currentRequestLock) { currentRequest = localRequest; } if (GuiThreadHelper.IsInGuiThread()) { IFilterDescriptor filterDescriptor = GetFilterDescriptor(); IList <ISortDescriptor> sortDescriptors = GetSortDescriptors(); IPagingRequest pagingRequest = GetPagingRequest(); Object[] contextInformation = GetContextInformation(); Model.IsBusy = true; ThreadPool.Queue((GenericViewModel <T> model) => { CacheContext.ExecuteWithCache <Object>(CacheProvider.GetCurrentCache(), delegate() { ConfigureCacheWithEagerLoads(Cache); PopulateAsync(model, filterDescriptor, sortDescriptors, pagingRequest, contextInformation, Cache, localRequest); return(null); }); }, Model); } else { IFilterDescriptor filterDescriptor = null; IList <ISortDescriptor> sortDescriptors = null; IPagingRequest pagingRequest = null; Object[] contextInformation = null; GuiThreadHelper.InvokeInGuiAndWait(delegate() { filterDescriptor = GetFilterDescriptor(); sortDescriptors = GetSortDescriptors(); pagingRequest = GetPagingRequest(); contextInformation = GetContextInformation(); Model.IsBusy = true; }); CacheContext.ExecuteWithCache <Object>(CacheProvider.GetCurrentCache(), delegate() { ConfigureCacheWithEagerLoads(Cache); PopulateAsync(Model, filterDescriptor, sortDescriptors, pagingRequest, contextInformation, Cache, localRequest); return(null); }); } }
protected void ExecuteFirePropertyChange(PropertyChangeSupport propertyChangeSupport, IList <IPropertyChangeExtension> extensions, Object obj, PropertyChangedEventArgs[] evnts, String[] propertyNames, Object[] oldValues, Object[] currentValues) { if (AsyncPropertyChangeActive) { GuiThreadHelper.InvokeInGui(delegate() { ExecuteFirePropertyChangeIntern(propertyChangeSupport, extensions, obj, evnts, propertyNames, oldValues, currentValues); }); } else { ExecuteFirePropertyChangeIntern(propertyChangeSupport, extensions, obj, evnts, propertyNames, oldValues, currentValues); } }
public virtual void OnCanExecuteChanged(Object sender, EventArgs e) { if (CanExecuteChanged != null) { if (GuiThreadHelper.IsInGuiThread()) { CanExecuteChanged.Invoke(this, EventArgs.Empty); } else { SyncContext.Send((object state) => { CanExecuteChanged.Invoke(this, EventArgs.Empty); }, null); } } }
public IBusyToken AcquireBusyToken() { BusyToken token = new BusyToken(this); bool changed; lock (pendingTokens) { pendingTokens.Add(token); changed = (pendingTokens.Count == 1); } GuiThreadHelper.InvokeInGui(delegate() { PropertyChanged(this, busyCountPCE); // Busy flag might evaluate to true if (changed) { PropertyChanged(this, isBusyPCE); } }); return(token); }
protected override void InterceptIntern(IInvocation invocation) { Attribute annotation = GetMethodLevelBehavior(invocation.Method); if (annotation is NoProxyAttribute) { InvokeTarget(invocation); return; } String methodName = invocation.Method.Name.ToLower(); Boolean?isAsyncBegin = null; if (methodName.StartsWith("begin")) { isAsyncBegin = true; methodName = methodName.Substring(5); } else if (methodName.StartsWith("end")) { isAsyncBegin = false; methodName = methodName.Substring(3); } if (GuiThreadHelper.IsInGuiThread()) { if (!typeof(void).Equals(invocation.Method.ReturnType)) { throw new Exception("It is not allowed to call synchronuous methods from GUI thread. Please use '" + typeof(IThreadPool).FullName + "' to make this synchronuous call from a background thread"); } ThreadPool.Queue(delegate() { Intercept(invocation, methodName, annotation, isAsyncBegin); }); return; } Object result = Intercept(invocation, methodName, annotation, isAsyncBegin); invocation.ReturnValue = result; }
public void Finished(IBusyToken busyToken) { bool changed; lock (pendingTokens) { if (!pendingTokens.Remove(busyToken)) { throw new ArgumentException("Token not known"); } changed = (pendingTokens.Count == 0); } GuiThreadHelper.InvokeInGui(delegate() { PropertyChanged(this, busyCountPCE); // Busy flag might evaluate to false if (changed) { PropertyChanged(this, isBusyPCE); } }); }
public void test_PropertyChange_OutOfGuiThread() { HashMap <String, IMap <Thread, int> > counter = new HashMap <String, IMap <Thread, int> >(); PropertyChangedEventHandler handler = GetPropertyChangeHandlerForUI(counter); Thread workerThread = null; CountDownLatch latch = new CountDownLatch(1); ThreadPool.Queue(delegate() { workerThread = Thread.CurrentThread; Log.Info("Test()"); try { Material obj = EntityFactory.CreateEntity <Material>(); ((INotifyPropertyChanged)obj).PropertyChanged += handler; Log.Info("ICacheModification.set_Active(true)"); CacheModification.Active = true; try { Log.Info("set_Id"); obj.Id = 1; Log.Info("set_Id finished"); Assert.AssertEquals(0, counter.Count); } finally { Log.Info("ICacheModification.set_Active(false)"); CacheModification.Active = false; Log.Info("ICacheModification.set_Active(false) finished"); } WaitForUI(); Assert.AssertEquals(3, counter.Count); Log.Info(" set_Name"); obj.Name = "hallo"; WaitForUI(); Log.Info("set_Name finished"); Assert.AssertEquals(5, counter.Count); } finally { latch.CountDown(); } }); Log.Info("Await()"); latch.Await(); // Wait till the current ui queue has been processed completely GuiThreadHelper.InvokeInGuiAndWait(delegate() { // just an empty blocking delegate }); Assert.AssertEquals(5, counter.Count); Thread guiThread = ValueHolderContainerTestModule.dispatcherThread; IMap <Thread, int> toBeCreatedMap = counter.Get("ToBeCreated"); Assert.AssertNotNull(toBeCreatedMap); Assert.AssertEquals(1, toBeCreatedMap.Count); Assert.AssertTrue(toBeCreatedMap.ContainsKey(guiThread)); Assert.AssertEquals(1, toBeCreatedMap.Get(guiThread)); IMap <Thread, int> idMap = counter.Get("Id"); Assert.AssertNotNull(idMap); Assert.AssertEquals(1, idMap.Count); Assert.AssertTrue(idMap.ContainsKey(guiThread)); Assert.AssertEquals(1, idMap.Get(guiThread)); // uiThread is intended for Name in the case where asynchronous PCEs are allowed // but dispatched transparently in the UI IMap <Thread, int> nameMap = counter.Get("Name"); Assert.AssertNotNull(nameMap); Assert.AssertEquals(1, nameMap.Count); Assert.AssertTrue(idMap.ContainsKey(guiThread)); Assert.AssertEquals(1, nameMap.Get(guiThread)); IMap <Thread, int> toBeUpdatedMap = counter.Get("ToBeUpdated"); Assert.AssertNotNull(toBeUpdatedMap); Assert.AssertEquals(1, toBeUpdatedMap.Count); Assert.AssertTrue(toBeUpdatedMap.ContainsKey(guiThread)); Assert.AssertEquals(1, toBeUpdatedMap.Get(guiThread)); IMap <Thread, int> hasPendingChangesMap = counter.Get("HasPendingChanges"); Assert.AssertNotNull(hasPendingChangesMap); Assert.AssertEquals(1, hasPendingChangesMap.Count); Assert.AssertTrue(hasPendingChangesMap.ContainsKey(guiThread)); Assert.AssertEquals(2, hasPendingChangesMap.Get(guiThread)); }
protected void ProcessPendingOrelsAndObjRefs(ILinkedMap <Type, PrefetchPath[]> entityTypeToPrefetchPath, AlreadyHandledSet alreadyHandledSet, IdentityLinkedMap <ICacheIntern, IISet <IObjRef> > cacheToOrisLoadedHistory, IdentityLinkedMap <ICacheIntern, IISet <IObjRelation> > cacheToOrelsLoadedHistory, IdentityLinkedMap <ICacheIntern, IISet <IObjRef> > cacheToOrisToLoad, IdentityLinkedMap <ICacheIntern, IMap <IObjRelation, bool> > cacheToOrelsToLoad, List <PrefetchCommand> pendingPrefetchCommands, List <Object> hardRefList) { // all relation members where at least one instance of the owning entity type needs a prefetch on this member in the immediate next step MergePrefetchPathsCache mergePrefetchPathsCache = new MergePrefetchPathsCache(EntityMetaDataProvider); IdentityLinkedSet <Member> prioMembers = PrioMembersProvider.GetPrioMembers(entityTypeToPrefetchPath, pendingPrefetchCommands, mergePrefetchPathsCache); LoadAndAddOrels(cacheToOrelsToLoad, hardRefList, cacheToOrelsLoadedHistory, cacheToOrisToLoad, prioMembers); LoadAndAddOris(cacheToOrisToLoad, hardRefList, cacheToOrisLoadedHistory); while (pendingPrefetchCommands.Count > 0) { PrefetchCommand[] currentPrefetchCommands = pendingPrefetchCommands.ToArray(); // Clear the items to be ready for cascaded items in new batch recursion step pendingPrefetchCommands.Clear(); if (prioMembers.Count > 0) { for (int a = 0, size = currentPrefetchCommands.Length; a < size; a++) { PrefetchCommand prefetchCommand = currentPrefetchCommands[a]; DirectValueHolderRef valueHolder = prefetchCommand.valueHolder; if (!prioMembers.Contains(valueHolder.Member)) { currentPrefetchCommands[a] = null; pendingPrefetchCommands.Add(prefetchCommand); } } } GuiThreadHelper.InvokeInGuiAndWait(delegate() { ICacheModification cacheModification = CacheModification; ValueHolderContainerMixin valueHolderContainerMixin = ValueHolderContainerMixin; bool oldActive = cacheModification.Active; if (!oldActive) { cacheModification.Active = true; } try { foreach (PrefetchCommand prefetchCommand in currentPrefetchCommands) { if (prefetchCommand == null) { continue; } DirectValueHolderRef valueHolder = prefetchCommand.valueHolder; PrefetchPath[] cachePaths = prefetchCommand.prefetchPaths; RelationMember member = valueHolder.Member; // Merge the root prefetch path with the relative prefetch path cachePaths = mergePrefetchPathsCache.MergePrefetchPaths(member.ElementType, cachePaths, entityTypeToPrefetchPath); IObjRefContainer vhc = valueHolder.Vhc; ICacheIntern targetCache; bool doSetValue = false; if (valueHolder is IndirectValueHolderRef) { IndirectValueHolderRef valueHolderKey = (IndirectValueHolderRef)valueHolder; targetCache = valueHolderKey.RootCache; } else { targetCache = ((IValueHolderContainer)vhc).__TargetCache; doSetValue = true; } int relationIndex = vhc.Get__EntityMetaData().GetIndexByRelation(member); IObjRef[] objRefs = vhc.Get__ObjRefs(relationIndex); Object obj = valueHolderContainerMixin.GetValue(vhc, relationIndex, member, targetCache, objRefs, CacheDirective.FailEarly); if (doSetValue && obj != null) { member.SetValue(vhc, obj); } EnsureInitializedRelationsIntern3(obj, cachePaths, entityTypeToPrefetchPath, cacheToOrisToLoad, cacheToOrelsToLoad, cacheToOrisLoadedHistory, cacheToOrelsLoadedHistory, alreadyHandledSet, pendingPrefetchCommands); } } finally { if (!oldActive) { cacheModification.Active = false; } } }); // Remove all oris which have already been tried to load before if (cacheToOrisToLoad.Count == 0 && cacheToOrelsToLoad.Count == 0 && pendingPrefetchCommands.Count == 0) { return; } prioMembers = PrioMembersProvider.GetPrioMembers(entityTypeToPrefetchPath, pendingPrefetchCommands, mergePrefetchPathsCache); LoadAndAddOrels(cacheToOrelsToLoad, hardRefList, cacheToOrelsLoadedHistory, cacheToOrisToLoad, prioMembers); LoadAndAddOris(cacheToOrisToLoad, hardRefList, cacheToOrisLoadedHistory); } }
public void FilterValues() { if (DataSource == null) { return; } IList <T> readonlyDataSourceContext; if (DataSource is IModelMultiContainer <T> ) { readonlyDataSourceContext = ((IModelMultiContainer <T>)DataSource).Values; } else if (DataSource is IModelSingleContainer <T> ) { readonlyDataSourceContext = new List <T>(1); T value = ((IModelSingleContainer <T>)DataSource).Value; if (value != null) { readonlyDataSourceContext.Add(value); } } else { throw new NotSupportedException(typeof(IModelContainer).Name + " of type '" + DataSource.GetType() + "' not supported"); } SetBusy(); if (GuiThreadHelper.IsInGuiThread()) { // Create a 'safe copy' of the datasource from within gui thread IList <T> clonedDataSourceContext = new List <T>(readonlyDataSourceContext); ThreadPool.Queue(delegate() { try { IList <T> values = ClientFilter.Filter(clonedDataSourceContext); // This will not set the Values-IList<T> Pointer but will clear and reinit its content // This assumption is important because our unmodifiableValues-Property depends on it SyncContext.Send((object state) => { base.Values = values; }, null); } finally { SetUnbusy(); } }); } else { try { IList <T> clonedDataSourceContext = null; SyncContext.Send((object state) => { // Create a 'safe copy' of the datasource from within gui thread clonedDataSourceContext = new List <T>(readonlyDataSourceContext); }, null); IList <T> values = ClientFilter.Filter(clonedDataSourceContext); // This will not set the Values-IList<T> Pointer but will clear and reinit its content // This assumption is important because our unmodifiableValues-Property depends on it SyncContext.Send((object state) => { base.Values = values; }, null); } finally { SetUnbusy(); } } }
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(); } }); }
protected void DataChangedIntern(IDataChange dataChange, IList <Object> pausedEventTargets, IProcessResumeItem processResumeItem, CacheDependencyNode rootNode) { try { bool isLocalSource = dataChange.IsLocalSource; IList <IDataChangeEntry> deletes = dataChange.Deletes; IList <IDataChangeEntry> updates = dataChange.Updates; IList <IDataChangeEntry> inserts = dataChange.Inserts; CHashSet <Type> occuringTypes = new CHashSet <Type>(); CHashSet <IObjRef> deletesSet = new CHashSet <IObjRef>(); CHashSet <Type> directRelatingTypes = new CHashSet <Type>(); bool acquirementSuccessful = rootNode.rootCache.AcquireHardRefTLIfNotAlready(); try { for (int a = deletes.Count; a-- > 0;) { IDataChangeEntry deleteEntry = deletes[a]; Type entityType = deleteEntry.EntityType; occuringTypes.Add(entityType); if (deleteEntry is DirectDataChangeEntry) { // Ignore delete entries of unpersisted objects here continue; } ObjRef tempORI = new ObjRef(entityType, deleteEntry.IdNameIndex, deleteEntry.Id, deleteEntry.Version); deletesSet.Add(tempORI); } // Remove items from the cache only if they are really deleted/updates by a remote event // And not 'simulated' by a local source bool cleanupSecondLevelCaches = false; if (pausedEventTargets != null && (deletes.Count > 0 || updates.Count > 0) && !isLocalSource) { cleanupSecondLevelCaches = true; } else if (updates.Count > 0) { for (int a = updates.Count; a-- > 0;) { IDataChangeEntry updateEntry = updates[a]; Type entityType = updateEntry.EntityType; occuringTypes.Add(entityType); } } for (int a = inserts.Count; a-- > 0;) { IDataChangeEntry insertEntry = inserts[a]; Type entityType = insertEntry.EntityType; occuringTypes.Add(entityType); } EnsureMetaDataIsLoaded(occuringTypes, directRelatingTypes); if (cleanupSecondLevelCaches) { CleanupSecondLevelCaches(rootNode, deletesSet.ToList(), updates, occuringTypes); } BuildCacheChangeItems(rootNode, dataChange); rootNode.AggregateAllCascadedObjRefs(); ISet <IObjRef> intermediateDeletes = rootNode.lookForIntermediateDeletes(); ChangeSecondLevelCache(rootNode); if (rootNode.IsPendingChangeOnAnyChildCache()) { GuiThreadHelper.InvokeInGuiAndWait(delegate() { bool oldFailEarlyModeActive = AbstractCache.FailInCacheHierarchyModeActive; AbstractCache.FailInCacheHierarchyModeActive = true; try { ChangeFirstLevelCaches(rootNode, intermediateDeletes); } finally { AbstractCache.FailInCacheHierarchyModeActive = oldFailEarlyModeActive; } }); } } finally { rootNode.rootCache.ClearHardRefs(acquirementSuccessful); } } finally { if (processResumeItem != null) { processResumeItem.ResumeProcessingFinished(); } } }
protected virtual void PopulateAsync(GenericViewModel <T> model, IFilterDescriptor filterDescriptor, IList <ISortDescriptor> sortDescriptors, IPagingRequest pagingRequest, Object[] contextInformation, ICache cache, Object localRequest) { lock (currentRequestLock) { // Early check here, but more important check in the finally-SyncContext. // We will not update the ViewModel, if this request is not the current request (hence Populate was recalled // since this request was initiated). // An example where this is important would be a screen, where the user can enter search criteria and start // a corresponding search, while the screen is still loading data from a preceeding request. In this case, the // result of the second search could be retrieved before the first one, leading to wrong data in the screen. // // ToDo: Is there a scenario where the same VMDCC is used with multiple VMs or different Caches? // If so, localRequest and currentRequest must contain the VM and Cache references to compare them! if (!Object.ReferenceEquals(localRequest, currentRequest)) { return; } } IList <T> initialEntities = null; IPagingResponse pagingResponse = null; try { if (hasPagedViewModel) { pagingResponse = ((IPagingRefresher <T>)Refresher).Populate(filterDescriptor, sortDescriptors, pagingRequest, contextInformation); initialEntities = new List <T>(); foreach (Object obj in pagingResponse.Result) { initialEntities.Add((T)obj); } } else { if (filterDescriptor != null || sortDescriptors != null) { contextInformation = new Object[2]; contextInformation[0] = filterDescriptor; contextInformation[1] = sortDescriptors; } initialEntities = ((IRefresher <T>)Refresher).Populate(contextInformation); } } catch (Exception e) { if (Log.ErrorEnabled) { Log.Error(e); } } finally { GuiThreadHelper.InvokeInGui(delegate() { lock (currentRequestLock) { if (!Object.ReferenceEquals(localRequest, currentRequest)) { return; } } try { if (IsRefreshedDataValid(contextInformation)) { if (initialEntities != null) { if (ToBeCreatedOnTop) { // ToBeCreated entities are never part of the initialEntities, so no doublette check necessary foreach (T entity in model.Objects) { if ((entity is IDataObject) && ((IDataObject)entity).ToBeCreated) { initialEntities.Insert(0, entity); } } } model.Clear(); for (int a = 0, size = initialEntities.Count; a < size; a++) { T item = initialEntities[a]; model.InsertAt(a, item); } } // Important to update the sorting states (if the provider disables gridviews own sorting mechanism): if (hasPagedViewModel) { UpdatePagingInformation(pagingResponse); } UpdateAfterDCE(); } } catch (Exception ex) { if (Log.ErrorEnabled) { Log.Error(ex); } } finally { model.IsBusy = false; } }); } }
protected virtual void RevertChangesIntern(IRevertChangesSavepoint savepoint, IList <Object> objectsToRevert, bool globally, RevertChangesFinishedCallback revertChangesFinishedCallback) { // Store the RevertChangesFinishedCallback from this thread on the stack and set the property null (for following calls): if (objectsToRevert == null || objectsToRevert.Count == 0) { if (revertChangesFinishedCallback != null) { revertChangesFinishedCallback.Invoke(true); } return; } if (globally) { GuiThreadHelper.InvokeOutOfGui(delegate() { bool success = false; try { DataChangeEvent dataChange = new DataChangeEvent(); dataChange.IsLocalSource = true; dataChange.Inserts = new List <IDataChangeEntry>(0); dataChange.Updates = new List <IDataChangeEntry>(); dataChange.Deletes = new List <IDataChangeEntry>(); for (int a = objectsToRevert.Count; a-- > 0;) { Object objectToRevert = objectsToRevert[a]; IEntityMetaData metaData = ((IEntityMetaDataHolder)objectToRevert).Get__EntityMetaData(); Object id = metaData.IdMember.GetValue(objectToRevert, false); if (id == null) { dataChange.Deletes.Add(new DirectDataChangeEntry(objectToRevert)); continue; } dataChange.Updates.Add(new DataChangeEntry(metaData.EntityType, ObjRef.PRIMARY_KEY_INDEX, id, null)); } EventDispatcher.DispatchEvent(dataChange, DateTime.Now, -1); success = true; } finally { if (revertChangesFinishedCallback != null) { revertChangesFinishedCallback.Invoke(success); } } }); } else { // Commented the following part from Ambeth 0.130 and use the part from Ambeth 0.129 due to a deadlock in the merge process: //GuiThreadHelper.InvokeOutOfGui(delegate() //{ // bool success1 = false; // try // { // IList<IDataChangeEntry> directObjectDeletes = new List<IDataChangeEntry>(); // IList<Object> initializedObjects = MergeController.ScanForInitializedObjects(objectsToRevert, true, null); // IList<IObjRef> orisToRevert = new List<IObjRef>(); // ISet<Object> persistedObjectsToRevert = new IdentityHashSet<Object>(); // for (int a = initializedObjects.Count; a-- > 0; ) // { // Object objectToRevert = initializedObjects[a]; // IEntityMetaData metaData = EntityMetaDataProvider.GetMetaData(objectToRevert.GetType()); // Object id = metaData.IdMember.GetValue(objectToRevert, false); // if (id == null) // { // directObjectDeletes.Add(new DirectDataChangeEntry(objectToRevert)); // continue; // } // persistedObjectsToRevert.Add(objectToRevert); // orisToRevert.Add(new ObjRef(metaData.EntityType, ObjRef.PRIMARY_KEY_INDEX, id, null)); // } // IList<Object> hardRefsToRootCacheValues = RootCache.GetObjects(orisToRevert, CacheDirective.CacheValueResult | CacheDirective.ReturnMisses); // for (int a = orisToRevert.Count; a-- > 0; ) // { // if (hardRefsToRootCacheValues[a] == null) // { // // Object could not be loaded/retrieved any more. So the ori refers to an invalid object // // We can not revert invalid objects and currently ignore them. They will raise exceptions if they will // // be tried to persist in a merge process any time in the future // orisToRevert.RemoveAt(a); // } // } // // We do nothing with the hardRef-list from the RootCache. It is only necessary to keep track of the instance reference on the stack // // To prohibit GC any potential WeakReferences in the meantime.... // GuiThreadHelper.InvokeInGuiAndWait(delegate() // { // IProcessResumeItem processResumeItem = WaitEventToResume(); // try // { // bool oldCacheModificationValue = CacheModification.IsActive; // CacheModification.IsActive = true; // bool oldFailEarlyModeActive = AbstractCache<Object>.FailEarlyModeActive; // AbstractCache<Object>.FailEarlyModeActive = true; // try // { // IList<IWritableCache> firstLevelCaches = FirstLevelCacheManager.SelectFirstLevelCaches(); // IList<Object> hardRefsToRootCacheValuesHere = hardRefsToRootCacheValues; // foreach (IWritableCache firstLevelCache in firstLevelCaches) // { // IList<Object> persistedObjectsInThisCache = firstLevelCache.GetObjects(orisToRevert, CacheDirective.FailEarly); // for (int a = persistedObjectsInThisCache.Count; a-- > 0; ) // { // Object persistedObjectInThisCache = persistedObjectsInThisCache[a]; // if (!persistedObjectsToRevert.Contains(persistedObjectInThisCache)) // { // continue; // } // RootCache.ApplyValues(persistedObjectInThisCache, (ICacheIntern)firstLevelCache); // } // } // for (int a = objectsToRevert.Count; a-- > 0; ) // { // Object objectToRevert = objectsToRevert[a]; // if (objectToRevert is IDataObject) // { // // Objects which are specified to be reverted loose their delete flag // ((IDataObject)objectToRevert).ToBeDeleted = false; // } // } // } // finally // { // AbstractCache<Object>.FailEarlyModeActive = oldFailEarlyModeActive; // CacheModification.IsActive = oldCacheModificationValue; // } // } // finally // { // if (processResumeItem != null) // { // processResumeItem.ResumeProcessingFinished(); // processResumeItem = null; // } // } // }); // if (directObjectDeletes.Count > 0) // { // DataChangeEvent dataChange = DataChangeEvent.Create(0, 0, 0); // dataChange.Deletes = directObjectDeletes; // EventDispatcher.DispatchEvent(dataChange, DateTime.Now, -1); // } // success1 = true; // } // finally // { // if (revertChangesFinishedCallback != null) // { // revertChangesFinishedCallback.Invoke(success1); // } // } //}); // Here comes the part from Ambeth 0.129: GuiThreadHelper.InvokeOutOfGui(delegate() { bool success1 = false; bool?success2 = null; bool?success3 = null; try { IList <IDataChangeEntry> directObjectDeletes = new List <IDataChangeEntry>(); List <IObjRef> objRefs = new List <IObjRef>(); List <ValueHolderRef> valueHolderKeys = new List <ValueHolderRef>(); IList <Object> initializedObjects = MergeController.ScanForInitializedObjects(objectsToRevert, true, null, objRefs, valueHolderKeys); IList <IObjRef> orisToRevert = new List <IObjRef>(); ISet <Object> persistedObjectsToRevert = new IdentityHashSet <Object>(); for (int a = initializedObjects.Count; a-- > 0;) { Object objectToRevert = initializedObjects[a]; IEntityMetaData metaData = ((IEntityMetaDataHolder)objectToRevert).Get__EntityMetaData(); Object id = metaData.IdMember.GetValue(objectToRevert, false); if (id == null) { directObjectDeletes.Add(new DirectDataChangeEntry(objectToRevert)); continue; } persistedObjectsToRevert.Add(objectToRevert); orisToRevert.Add(new ObjRef(metaData.EntityType, ObjRef.PRIMARY_KEY_INDEX, id, null)); } IList <Object> hardRefsToRootCacheValues = RootCache.GetObjects(orisToRevert, CacheDirective.CacheValueResult | CacheDirective.ReturnMisses); for (int a = orisToRevert.Count; a-- > 0;) { if (hardRefsToRootCacheValues[a] == null) { // Object could not be loaded/retrieved any more. So the ori refers to an invalid object // We can not revert invalid objects and currently ignore them. They will raise exceptions if they will // be tried to persist in a merge process any time in the future orisToRevert.RemoveAt(a); } } // We do nothing with the hardRef-list from the RootCache. It is only necessary to keep track of the instance reference on the stack // To prohibit GC any potential WeakReferences in the meantime.... success2 = false; GuiThreadHelper.InvokeInGui(delegate(Object state) { WaitEventToResume(delegate(IProcessResumeItem processResumeItem) { try { bool oldCacheModificationValue = CacheModification.Active; CacheModification.Active = true; bool oldFailEarlyModeActive = AbstractCache.FailInCacheHierarchyModeActive; AbstractCache.FailInCacheHierarchyModeActive = true; try { IList <IWritableCache> firstLevelCaches = FirstLevelCacheManager.SelectFirstLevelCaches(); IList <Object> hardRefsToRootCacheValuesHere = hardRefsToRootCacheValues; foreach (IWritableCache firstLevelCache in firstLevelCaches) { IList <Object> persistedObjectsInThisCache = firstLevelCache.GetObjects(orisToRevert, CacheDirective.FailEarly); for (int a = persistedObjectsInThisCache.Count; a-- > 0;) { Object persistedObjectInThisCache = persistedObjectsInThisCache[a]; if (!persistedObjectsToRevert.Contains(persistedObjectInThisCache)) { continue; } RootCache.ApplyValues(persistedObjectInThisCache, (ICacheIntern)firstLevelCache, null); } } for (int a = objectsToRevert.Count; a-- > 0;) { Object objectToRevert = objectsToRevert[a]; if (objectToRevert is IDataObject) { // Objects which are specified to be reverted loose their flags ((IDataObject)objectToRevert).ToBeDeleted = false; } } if (directObjectDeletes.Count == 0) { success2 = true; return; } } finally { AbstractCache.FailInCacheHierarchyModeActive = oldFailEarlyModeActive; CacheModification.Active = oldCacheModificationValue; } } finally { if (processResumeItem != null) { processResumeItem.ResumeProcessingFinished(); } } success3 = false; GuiThreadHelper.InvokeOutOfGui(delegate() { try { DataChangeEvent dataChange = DataChangeEvent.Create(0, 0, 0); dataChange.Deletes = directObjectDeletes; EventDispatcher.DispatchEvent(dataChange, DateTime.Now, -1); success3 = true; } finally { if (revertChangesFinishedCallback != null) { revertChangesFinishedCallback.Invoke(success3.Value); } } }); success2 = true; }, delegate(Exception e) { if (revertChangesFinishedCallback != null && success3 == null) { revertChangesFinishedCallback.Invoke(success2.Value); } }); }, null); success1 = true; } finally { if (revertChangesFinishedCallback != null && success2 == null && success3 == null) { revertChangesFinishedCallback.Invoke(success1); } } }); } }
protected override void InterceptIntern(IInvocation invocation) { if (GuiThreadHelper != null && GuiThreadHelper.IsInGuiThread()) { throw new Exception("It is not allowed to call this interceptor from GUI thread"); } lock (clientLock) { if (connectionChangePending) { // Wait till the connection change finished Monitor.Wait(clientLock); } } DateTime m1 = DateTime.Now; MethodInfo method = invocation.Method; String url = ServiceBaseUrl + "/" + ServiceName + "/" + method.Name; HttpWebRequest webRequest; #if SILVERLIGHT if (HttpUseClient) { webRequest = (HttpWebRequest)WebRequestCreator.ClientHttp.Create(new Uri(url)); } else { webRequest = WebRequest.CreateHttp(url); } #else webRequest = (HttpWebRequest)WebRequest.Create(url); webRequest.Proxy = null; webRequest.KeepAlive = true; #endif Object result = null; bool hasResult = false; Exception ex = null; lock (webRequest) { webRequest.Accept = "text/plain"; if (HttpAcceptEncodingZipped) { TryToSetHeader(HttpRequestHeader.AcceptEncoding, webRequest, "gzip"); webRequest.Headers["Accept-Encoding-Workaround"] = "gzip"; } SetAuthorization(webRequest); if (invocation.Arguments.Length == 0) { webRequest.Method = "GET"; webRequest.BeginGetResponse(delegate(IAsyncResult asyncResult2) { try { HttpWebResponse response = (HttpWebResponse)webRequest.EndGetResponse(asyncResult2); using (Stream responseStream = response.GetResponseStream()) using (Stream memoryStream = new MemoryStream()) { int b; while ((b = responseStream.ReadByte()) != -1) { memoryStream.WriteByte((byte)b); } memoryStream.Position = 0; try { Stream deflateStream = GetResponseStream(response, memoryStream); result = CyclicXmlHandler.ReadFromStream(deflateStream); } catch (XmlTypeNotFoundException) { throw; } catch (Exception) { memoryStream.Position = 0; result = CyclicXmlHandler.ReadFromStream(memoryStream); } } hasResult = true; } catch (WebException e) { ex = ParseWebException(e); using (HttpWebResponse response = (HttpWebResponse)e.Response) { HandleException(e, response); } } catch (Exception e) { Log.Error(e); ex = e; } finally { lock (webRequest) { Monitor.PulseAll(webRequest); } } }, null); } else { webRequest.Method = "POST"; webRequest.ContentType = "text/plain"; if (HttpContentEncodingZipped) { TryToSetHeader(HttpRequestHeader.ContentEncoding, webRequest, "gzip"); webRequest.Headers["Content-Encoding-Workaround"] = "gzip"; } webRequest.BeginGetRequestStream(delegate(IAsyncResult asyncResult) { try { using (Stream stream = webRequest.EndGetRequestStream(asyncResult)) #if SILVERLIGHT using (Stream deflateStream = HttpContentEncodingZipped ? new GZipStream(stream, CompressionMode.Compress, CompressionLevel.BestCompression, false) : stream) #else using (Stream deflateStream = HttpContentEncodingZipped ? new GZipStream(stream, CompressionMode.Compress, false) : stream) #endif { CyclicXmlHandler.WriteToStream(deflateStream, invocation.Arguments); } webRequest.BeginGetResponse(delegate(IAsyncResult asyncResult2) { DateTime m4 = DateTime.Now; try { HttpWebResponse response = (HttpWebResponse)webRequest.EndGetResponse(asyncResult2); DateTime m5 = DateTime.Now; using (Stream responseStream = response.GetResponseStream()) using (Stream memoryStream = new MemoryStream()) { int b; while ((b = responseStream.ReadByte()) != -1) { memoryStream.WriteByte((byte)b); } memoryStream.Position = 0; try { Stream deflateStream = GetResponseStream(response, memoryStream); result = CyclicXmlHandler.ReadFromStream(deflateStream); } catch (XmlTypeNotFoundException) { throw; } catch (Exception) { memoryStream.Position = 0; result = CyclicXmlHandler.ReadFromStream(memoryStream); } } hasResult = true; } catch (WebException e) { ex = ParseWebException(e); using (HttpWebResponse response = (HttpWebResponse)e.Response) { HandleException(e, response); } } catch (Exception e) { ex = e; } finally { lock (webRequest) { Monitor.PulseAll(webRequest); } } }, null); } catch (Exception e) { ex = e; lock (webRequest) { Monitor.PulseAll(webRequest); } } }, null); } while (!hasResult && ex == null) { Monitor.Wait(webRequest); } } if (result is AmbethServiceException) { ex = ParseServiceException((AmbethServiceException)result); throw new Exception("Error occured while calling " + webRequest.Method + " " + webRequest.RequestUri, ex); } if (ex != null) { if (ex is WebException) { throw new Exception(ex.Message + "\r\rError occured while calling " + webRequest.Method + " " + webRequest.RequestUri + ". " + CyclicXmlHandler.Write(invocation.Arguments), ex); } throw new Exception("Error occured while calling " + webRequest.Method + " " + webRequest.RequestUri + ". " + CyclicXmlHandler.Write(invocation.Arguments), ex); } if (!hasResult) { throw new Exception("This must never happen"); } invocation.ReturnValue = ConvertToExpectedType(method.ReturnType, result); }