コード例 #1
0
        protected override async ValueTask <IComputed <T> > ComputeAsync(
            InterceptedInput input, IComputed <T>?existing,
            CancellationToken cancellationToken)
        {
            var tag      = VersionGenerator.Next();
            var computed = CreateComputed(input, tag);

            try {
                using var _ = Computed.ChangeCurrent(computed);
                var result = input.InvokeOriginalFunction(cancellationToken);
                if (input.Method.ReturnsValueTask)
                {
                    var output = await((ValueTask <T>)result).ConfigureAwait(false);
                    computed.TrySetOutput(output);
                }
                else
                {
                    var output = await((Task <T>)result).ConfigureAwait(false);
                    computed.TrySetOutput(output);
                }
            }
            catch (OperationCanceledException) {
                throw;
            }
            catch (Exception e) {
                computed.TrySetOutput(Result.Error <T>(e));
                // Weird case: if the output is already set, all we can
                // is to ignore the exception we've just caught;
                // throwing it further will probably make it just worse,
                // since the the caller have to take this scenario into acc.
            }
            return(computed);
        }
コード例 #2
0
        protected override async ValueTask <IComputed <T> > ComputeAsync(
            InterceptedInput input, IComputed <T>?cached,
            CancellationToken cancellationToken)
        {
            var tag    = LTagGenerator.Next();
            var method = Method;
            var output = new Computed <InterceptedInput, T>(method.Options, input, tag);

            try {
                using var _ = Computed.ChangeCurrent(output);
                var resultTask = input.InvokeOriginalFunction(cancellationToken);
                if (method.ReturnsComputed)
                {
                    if (method.ReturnsValueTask)
                    {
                        var task = (ValueTask <IComputed <T> >)resultTask;
                        await task.ConfigureAwait(false);

                        // output == task.Result here, so no need to call output.TrySetOutput(...)
                    }
                    else
                    {
                        var task = (Task <IComputed <T> >)resultTask;
                        await task.ConfigureAwait(false);

                        // output == task.Result here, so no need to call output.TrySetOutput(...)
                    }
                }
                else
                {
                    if (method.ReturnsValueTask)
                    {
                        var task  = (ValueTask <T>)resultTask;
                        var value = await task.ConfigureAwait(false);

                        output.TrySetOutput(value !);
                    }
                    else
                    {
                        var task  = (Task <T>)resultTask;
                        var value = await task.ConfigureAwait(false);

                        output.TrySetOutput(value !);
                    }
                }
            }
            catch (OperationCanceledException) {
                throw;
            }
            catch (Exception e) {
                output.TrySetOutput(Result.Error <T>(e));
                // Weird case: if the output is already set, all we can
                // is to ignore the exception we've just caught;
                // throwing it further will probably make it just worse,
                // since the the caller have to take this scenario into acc.
            }
            return(output);
        }