示例#1
0
        T IContextCache.GetOrAddContext <T>(ContextFactory <T> contextFactory)
        {
            try
            {
                IContextValue <T> context = null;

                IContextCollection currentCollection;
                do
                {
                    T existingValue;
                    if (_collection.TryGetContext(out existingValue))
                    {
                        return(existingValue);
                    }

                    IContextValue <T> contextProperty = context ?? (context = new ContextValue <T>(contextFactory()));

                    currentCollection = Volatile.Read(ref _collection);

                    Interlocked.CompareExchange(ref _collection, currentCollection.Add(contextProperty), currentCollection);
                } while (currentCollection == Volatile.Read(ref _collection));

                return(context.Value);
            }
            catch (Exception exception)
            {
                throw new ContextFactoryException($"The payload factory faulted: {TypeCache<T>.ShortName}", exception);
            }
        }
示例#2
0
        T IContextCache.AddOrUpdateContext <T>(ContextFactory <T> addFactory, UpdateContextFactory <T> updateFactory)
        {
            try
            {
                T previousValue           = null;
                IContextValue <T> context = null;

                IContextCollection currentCollection;
                do
                {
                    T existingValue;
                    if (_collection.TryGetContext(out existingValue))
                    {
                        if (context == null || previousValue != existingValue)
                        {
                            context = new ContextValue <T>(updateFactory(existingValue));
                        }

                        previousValue = existingValue;

                        currentCollection = Volatile.Read(ref _collection);

                        Interlocked.CompareExchange(ref _collection, currentCollection.Add(context), currentCollection);
                    }
                    else
                    {
                        if (context == null)
                        {
                            context = new ContextValue <T>(addFactory());
                        }

                        currentCollection = Volatile.Read(ref _collection);

                        Interlocked.CompareExchange(ref _collection, currentCollection.Add(context), currentCollection);
                    }
                } while (currentCollection == Volatile.Read(ref _collection));

                return(context.Value);
            }
            catch (Exception exception)
            {
                throw new ContextFactoryException($"The payload factory faulted: {TypeCache<T>.ShortName}", exception);
            }
        }