Пример #1
0
        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);
                });
            }
        }
Пример #2
0
        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");
            });
        }
Пример #3
0
 protected virtual void RaisePropertyChanged(String propertyName)
 {
     GuiThreadHelper.InvokeInGui(delegate()
     {
         var localEventHandler = PropertyChanged;
         if (localEventHandler != null)
         {
             localEventHandler.Invoke(this, new PropertyChangedEventArgs(propertyName));
         }
     });
 }
Пример #4
0
 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);
     }
 }
Пример #5
0
        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);
        }
Пример #6
0
        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);
                }
            });
        }
        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;
                    }
                });
            }
        }
Пример #8
0
        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);
                        }
                    }
                });
            }
        }