async Task UpdateProcessingHandler(Update update)
        {
            UpdateContext pendingUpdateContext = null;
            IServiceScope servicesScope        = Services.CreateScope();

            try
            {
                var cancellationTokenSource = new CancellationTokenSource();

                //Create context.
                var updateContext = new UpdateContext(
                    update,
                    BotContext,
                    servicesScope.ServiceProvider,
                    cancellationTokenSource.Token
                    );

                //Create hidden context.
                var hiddenUpdateContext = new HiddenUpdateContext(
                    cancellationTokenSource,
                    DateTime.Now,
                    LoggingAdvancedOptions
                    );
                updateContext.Properties[HiddenUpdateContext.DictKeyName] = hiddenUpdateContext;

                _logger.LogTrace("'{0}' created.", updateContext);

                //Add to pending list.
                _pendingUpdateContexts.Add(
                    updateContext
                    );
                pendingUpdateContext = updateContext;

                //Execute.
                await _updateProcessingDelegate.Invoke(updateContext, async() => { });
            }
            finally
            {
                //Remove from pending list.
                if (pendingUpdateContext != null)
                {
                    pendingUpdateContext.Dispose();
                    _pendingUpdateContexts.TryRemove(pendingUpdateContext);
                    _logger.LogTrace("'{0}' disposed and removed from pending.", pendingUpdateContext);
                }
                servicesScope.Dispose();
            }
        }
Beispiel #2
0
        public UpdateProcessingDelegate Build()
        {
            //For each new iteration and each middleware from stack processingDelegate_OfIteration will contain delegate to execute
            //all next middleware.
            //"next" delegate for current iteration. Started with empty delegate for last middleware.
            UpdateProcessingDelegate processingDelegate_OfIteration = async(UpdateContext ctx, Func <Task> nextFunc) => { };

            while (_updateProcessingDelegates.Count > 0)
            {
                var prevProcessingDelegate    = processingDelegate_OfIteration;
                var currentProcessingDelegate = _updateProcessingDelegates.Pop();

                processingDelegate_OfIteration = async(UpdateContext ctx, Func <Task> mostNext) =>
                {
                    Func <Task> next = async() =>
                    {
                        await prevProcessingDelegate.Invoke(ctx, mostNext);
                    };

                    //Force exit.
                    if (ctx.ForceExitRequested)
                    {
                        return;
                    }

                    //Execute current.
                    await currentProcessingDelegate.Invoke(ctx, next);
                };
            }

            //Just add some checks.
            UpdateProcessingDelegate res = async(UpdateContext ctx, Func <Task> next) =>
            {
                if (ctx == null)
                {
                    throw new ArgumentNullException(nameof(ctx), "Null context passed to UpdateProcessingDelegate.");
                }
                if (next == null)
                {
                    throw new ArgumentNullException(nameof(next), "Null 'next' passed to UpdateProcessingDelegate.");
                }
                await processingDelegate_OfIteration.Invoke(ctx, next);
            };

            return(res);
        }