Beispiel #1
0
        public static async Task <IComputed <T> > CaptureAsync <T>(Func <CancellationToken, Task <T> > producer, CancellationToken cancellationToken = default)
        {
            using var ccs = ComputeContext.New(CallOptions.Capture).Activate();
            IComputed <T>?result;

            try {
                await producer.Invoke(cancellationToken).ConfigureAwait(false);
            }
            catch (OperationCanceledException) {
                throw;
            }
            catch (Exception) {
                result = ccs.Context.GetCapturedComputed <T>();
                if (result?.Error != null)
                {
                    return(result);
                }
                throw;
            }
            result = ccs.Context.GetCapturedComputed <T>();
            if (result == null)
            {
                throw Errors.NoComputedCaptured();
            }
            return(result);
        }
        public static IComputed <T>?TryGetExisting <T>(Func <ValueTask <T> > producer)
        {
            using var ccs = ComputeContext.New(CallOptions.TryGetExisting | CallOptions.Capture).Activate();
            var task = producer.Invoke();

            task.AssertCompleted(); // The must be always synchronous in this case
            return(ccs.Context.GetCapturedComputed <T>());
        }
Beispiel #3
0
        public static void Invalidate <T>(Func <ValueTask <T> > producer)
        {
            using var ccs = ComputeContext.New(CallOptions.Invalidate).Activate();
            var task = producer.Invoke();

            // The flow is essentially synchronous in this case, so...
            task.AssertCompleted();
        }
        internal ComputeContextScope(ComputeContext context)
        {
            var current = ComputeContext.CurrentLocal;

            _previousContext = current.Value;
            current.Value    = context;
            Context          = context;
        }
Beispiel #5
0
        // TryGetExisting

        public static IComputed <T>?TryGetExisting <T>(Func <Task <T> > producer)
        {
            using var ccs = ComputeContext.New(CallOptions.TryGetExisting | CallOptions.Capture).Activate();
            var task = producer.Invoke();

            // The flow is essentially synchronous in this case, so...
            task.AssertCompleted();
            return(ccs.Context.GetCapturedComputed <T>());
        }
 internal ComputeContextScope(ComputeContext context)
 {
     _oldContext = ComputeContext.Current;
     Context     = context;
     if (_oldContext != context)
     {
         ComputeContext.Current = context;
     }
 }
Beispiel #7
0
        // Capture & invalidate

        public static async Task <IComputed <T>?> TryCaptureAsync <T>(Func <CancellationToken, Task <T> > producer, CancellationToken cancellationToken = default)
        {
            using var ccs = ComputeContext.New(CallOptions.Capture).Activate();
            await producer.Invoke(cancellationToken).ConfigureAwait(false);

            var result = ccs.Context.GetCapturedComputed <T>();

            return(result);
        }
Beispiel #8
0
        static ComputeContext()
        {
            var allCallOptions = CallOptions.TryGetCached | CallOptions.Invalidate;
            var cache          = new Dictionary <CallOptions, ComputeContext>();

            for (var i = 0; i <= (int)allCallOptions; i++)
            {
                var action = (CallOptions)i;
                cache[action] = new CachedComputeContext(action);
            }
            ContextCache = cache;
            Default      = New(default);
Beispiel #9
0
 internal ComputeContextScope(ComputeContext context)
 {
     Context                = context;
     _previousContext       = ComputeContext.Current;
     ComputeContext.Current = context;
 }