Exemple #1
0
        async Task IScorable <double> .PostAsync <Item>(IPostToBot inner, Item item, object state, CancellationToken token)
        {
            var verbTitle = (Tuple <string, string>)state;
            var verb      = verbTitle.Item1;
            var title     = verbTitle.Item2;

            switch (verb)
            {
            case Verbs.Snooze:
                await this.service.SnoozeAsync(title);

                break;

            case Verbs.Delete:
                await this.service.DeleteAsync(title);

                break;

            case Verbs.Disable:
                await this.service.UpsertAsync(title, when : null, state : false);

                break;

            case Verbs.Enable:
                await this.service.UpsertAsync(title, when : null, state : true);

                break;

            default:
                throw new NotImplementedException();
            }
        }
Exemple #2
0
 public ReactiveDialogTask(IPostToBot inner, IDialogStack stack, IStore <IFiberLoop <DialogTask> > store, Func <IDialog <object> > makeRoot)
 {
     SetField.NotNull(out this.inner, nameof(inner), inner);
     SetField.NotNull(out this.stack, nameof(stack), stack);
     SetField.NotNull(out this.store, nameof(store), store);
     SetField.NotNull(out this.makeRoot, nameof(makeRoot), makeRoot);
 }
Exemple #3
0
 public PersistentDialogTask(IPostToBot inner, Message message, IConnectorClient client, IBotToUser botToUser)
 {
     SetField.NotNull(out this.inner, nameof(inner), inner);
     SetField.NotNull(out this.message, nameof(message), message);
     SetField.NotNull(out this.client, nameof(client), client);
     SetField.NotNull(out this.botToUser, nameof(botToUser), botToUser);
 }
Exemple #4
0
 public PostUnhandledExceptionToUser(IPostToBot inner, IBotToUser botToUser, ResourceManager resources, TraceListener trace)
 {
     SetField.NotNull(out this.inner, nameof(inner), inner);
     SetField.NotNull(out this.botToUser, nameof(botToUser), botToUser);
     SetField.NotNull(out this.resources, nameof(resources), resources);
     SetField.NotNull(out this.trace, nameof(trace), trace);
 }
 public UserToBotFilter(IPostToBot inner, IBotToUser botToUser, ResourceManager resources, TraceListener trace)
 {
     this.messageProvider = (IMessageProvider)GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IMessageProvider));
     SetField.NotNull(out this.inner, nameof(inner), inner);
     SetField.NotNull(out this.botToUser, nameof(botToUser), botToUser);
     SetField.NotNull(out this.resources, nameof(resources), resources);
     SetField.NotNull(out this.trace, nameof(trace), trace);
 }
 public ScoringDialogTask(IPostToBot inner, IDialogStack stack, IComparer <Score> comparer, ITraits <Score> traits, params IScorable <Score>[] scorables)
 {
     SetField.NotNull(out this.inner, nameof(inner), inner);
     SetField.NotNull(out this.stack, nameof(stack), stack);
     SetField.NotNull(out this.comparer, nameof(comparer), comparer);
     SetField.NotNull(out this.traits, nameof(traits), traits);
     SetField.NotNull(out this.scorables, nameof(scorables), scorables);
 }
Exemple #7
0
        /// <summary>
        /// Post an item to the dialog context and poll the dialog context for any work to be done.
        /// </summary>
        /// <typeparam name="R">The type of the root dialog.</typeparam>
        /// <typeparam name="T">The type of the item.</typeparam>
        /// <param name="store">The dialog context store.</param>
        /// <param name="toBot">The item to be sent to the bot.</param>
        /// <param name="MakeRoot">The factory method for the root dialog.</param>
        /// <param name="token">An optional cancellation token.</param>
        /// <returns>A task representing the post operation.</returns>
        public static async Task PostAsync <T, R>(this IDialogContextStore store, T toBot, Func <IDialog <R> > MakeRoot, CancellationToken token = default(CancellationToken))
        {
            var context = await LoadAsync(store, MakeRoot);

            IPostToBot postToBot = context;
            await postToBot.PostAsync(toBot, token);

            store.Save(context);
        }
Exemple #8
0
        async Task IDialogStack.Forward <R, T>(IDialog <R> child, ResumeAfter <R> resume, T item, CancellationToken token)
        {
            IDialogStack stack = this;

            stack.Call(child, resume);
            await stack.PollAsync(token);

            IPostToBot postToBot = this;
            await postToBot.PostAsync(item, token);
        }
        async Task IScorable <double> .PostAsync <Item>(IPostToBot inner, Item item, object state, CancellationToken token)
        {
            var message = (IMessageActivity)(object)item;

            this.stack.Reset();
            botData.UserData.Clear();
            botData.PrivateConversationData.Clear();
            await botData.FlushAsync(token);

            await botToUser.PostAsync(Resources.UserProfileDeleted);
        }
Exemple #10
0
        async Task IScorable <double> .PostAsync <Item>(IPostToBot inner, Item item, object state, CancellationToken token)
        {
            var dialog = new CalculatorDialog();

            // let's strip off the prefix in favor of the actual arithmetic expression
            var message = (Message)(object)item;

            message.Text = (string)state;

            await this.stack.Forward(dialog.Void <double, Message>(), null, item, token);

            await this.stack.PollAsync(token);
        }
Exemple #11
0
        /// <summary>
        /// Post an item to the dialog task and poll the dialog task for any work to be done.
        /// </summary>
        /// <typeparam name="R">The type of the root dialog.</typeparam>
        /// <typeparam name="T">The type of the item.</typeparam>
        /// <param name="task">The dialog task.</param>
        /// <param name="toBot">The item to be sent to the bot.</param>
        /// <param name="MakeRoot">The factory method for the root dialog.</param>
        /// <param name="token">An optional cancellation token.</param>
        /// <returns>A task representing the post operation.</returns>
        public static async Task PostAsync <T, R>(this IDialogTask task, T toBot, Func <IDialog <R> > MakeRoot, CancellationToken token = default(CancellationToken))
        {
            await LoadAsync(task, MakeRoot, token);

            IPostToBot postToBot = task;

            try
            {
                await postToBot.PostAsync(toBot, token);
            }
            catch
            {
                task.Reset();
                throw;
            }

            task.Save();
        }
        /// <summary>
        /// Post an item to the dialog context and poll the dialog context for any work to be done.
        /// </summary>
        /// <typeparam name="R">The type of the root dialog.</typeparam>
        /// <typeparam name="T">The type of the item.</typeparam>
        /// <param name="store">The dialog context store.</param>
        /// <param name="toBot">The item to be sent to the bot.</param>
        /// <param name="MakeRoot">The factory method for the root dialog.</param>
        /// <param name="token">An optional cancellation token.</param>
        /// <returns>A task representing the post operation.</returns>
        public static async Task PostAsync <T, R>(this IDialogContextStore store, T toBot, Func <IDialog <R> > MakeRoot, CancellationToken token = default(CancellationToken))
        {
            IDialogContextInternal context;

            if (MakeRoot != null)
            {
                context = await LoadAsync(store, MakeRoot);
            }
            else
            {
                if (!store.TryLoad(out context))
                {
                    throw new InvalidOperationException("Cannot resume on an empty call stack!");
                }
            }

            IPostToBot postToBot = context;
            await postToBot.PostAsync(toBot, token);

            store.Save(context);
        }
Exemple #13
0
 public SerializingDialogTask(IPostToBot inner, ResumptionCookie cookie, IScope <ResumptionCookie> scopeForCookie)
 {
     SetField.NotNull(out this.inner, nameof(inner), inner);
     SetField.NotNull(out this.cookie, nameof(cookie), cookie);
     SetField.NotNull(out this.scopeForCookie, nameof(scopeForCookie), scopeForCookie);
 }
Exemple #14
0
 public LocalizedDialogTask(IPostToBot inner)
 {
     SetField.NotNull(out this.inner, nameof(inner), inner);
 }
Exemple #15
0
 public ExceptionTranslationDialogTask(IPostToBot inner)
 {
     SetField.NotNull(out this.inner, nameof(inner), inner);
 }
Exemple #16
0
        protected override void Load(ContainerBuilder builder)
        {
            base.Load(builder);

            builder.RegisterModule(new FiberModule <DialogTask>());

            // singleton components

            builder
            .Register(c => new ResourceManager("Microsoft.Bot.Builder.Resource.Resources", typeof(Resource.Resources).Assembly))
            .As <ResourceManager>()
            .SingleInstance();

            // every lifetime scope is driven by a message

            builder
            .Register((c, p) => p.TypedAs <IMessageActivity>())
            .AsSelf()
            .AsImplementedInterfaces()
            .InstancePerMatchingLifetimeScope(LifetimeScopeTag);

            // make the address and cookie available for the lifetime scope

            builder
            .RegisterType <Address>()
            .AsSelf()
            .InstancePerMatchingLifetimeScope(LifetimeScopeTag);

            builder
            .RegisterType <ResumptionCookie>()
            .AsSelf()
            .InstancePerMatchingLifetimeScope(LifetimeScopeTag);

            // components not marked as [Serializable]
            builder
            .RegisterType <MicrosoftAppCredentials>()
            .AsSelf()
            .SingleInstance();

            builder
            .RegisterType <BotIdResolver>()
            .As <IBotIdResolver>()
            .SingleInstance();

            builder
            // not resolving IEqualityComparer<Address> from container because it's a very local policy
            // and yet too broad of an interface.  could explore using tags for registration overrides.
            .Register(c => new LocalMutualExclusion <Address>(new ConversationAddressComparer()))
            .As <IScope <Address> >()
            .SingleInstance();

            builder
            .Register(c => new ConnectorClientFactory(c.Resolve <IMessageActivity>(), c.Resolve <MicrosoftAppCredentials>()))
            .As <IConnectorClientFactory>()
            .InstancePerLifetimeScope();

            builder
            .Register(c => c.Resolve <IConnectorClientFactory>().MakeConnectorClient())
            .As <IConnectorClient>()
            .InstancePerLifetimeScope();

            builder
            .Register(c => c.Resolve <IConnectorClientFactory>().MakeStateClient())
            .As <IStateClient>()
            .InstancePerLifetimeScope();

            builder
            .Register(c => new DetectChannelCapability(c.Resolve <IMessageActivity>()))
            .As <IDetectChannelCapability>()
            .InstancePerLifetimeScope();

            builder
            .Register(c => c.Resolve <IDetectChannelCapability>().Detect())
            .As <IChannelCapability>()
            .InstancePerLifetimeScope();

            builder.RegisterType <ConnectorStore>()
            .AsSelf()
            .InstancePerLifetimeScope();

            // If bot wants to use InMemoryDataStore instead of
            // ConnectorStore, the below registration should be used
            // as the inner IBotDataStore for CachingBotDataStore

            /*builder.RegisterType<InMemoryDataStore>()
             *  .AsSelf()
             *  .SingleInstance(); */

            builder.Register(c => new CachingBotDataStore(c.Resolve <ConnectorStore>(),
                                                          CachingBotDataStoreConsistencyPolicy.ETagBasedConsistency))
            .As <IBotDataStore <BotData> >()
            .AsSelf()
            .InstancePerLifetimeScope();

            builder
            .RegisterType <JObjectBotData>()
            .As <IBotData>()
            .InstancePerLifetimeScope();

            builder
            .Register(c => new BotDataBagStream(c.Resolve <IBotData>().PrivateConversationData, BlobKey))
            .As <Stream>()
            .InstancePerLifetimeScope();

            builder
            .RegisterType <DialogTask>()
            .AsSelf()
            .As <IDialogStack>()
            .InstancePerLifetimeScope();

            // Scorable implementing "/deleteprofile"
            builder
            .RegisterType <DeleteProfileScorable>()
            .As <IScorable <double> >()
            .InstancePerLifetimeScope();

            builder
            .Register(c =>
            {
                var stack      = c.Resolve <IDialogStack>();
                var fromStack  = stack.Frames.Select(f => f.Target).OfType <IScorable <double> >();
                var fromGlobal = c.Resolve <IScorable <double>[]>();
                // since the stack of scorables changes over time, this should be lazy
                var lazyScorables = fromStack.Concat(fromGlobal);
                var scorable      = new CompositeScorable <double>(c.Resolve <IComparer <double> >(), c.Resolve <ITraits <double> >(), lazyScorables);
                return(scorable);
            })
            .InstancePerLifetimeScope()
            .AsSelf();

            builder
            .Register(c =>
            {
                var cc = c.Resolve <IComponentContext>();

                Func <IPostToBot> makeInner = () =>
                {
                    var task           = cc.Resolve <DialogTask>();
                    IDialogStack stack = task;
                    IPostToBot post    = task;
                    post = new ReactiveDialogTask(post, stack, cc.Resolve <IStore <IFiberLoop <DialogTask> > >(), cc.Resolve <Func <IDialog <object> > >());
                    post = new ExceptionTranslationDialogTask(post);
                    post = new LocalizedDialogTask(post);
                    post = new ScoringDialogTask <double>(post, stack, cc.Resolve <CompositeScorable <double> >());
                    return(post);
                };

                IPostToBot outer = new PersistentDialogTask(makeInner, cc.Resolve <IMessageActivity>(), cc.Resolve <IConnectorClient>(), cc.Resolve <IBotToUser>(), cc.Resolve <IBotData>());
                outer            = new SerializingDialogTask(outer, cc.Resolve <Address>(), c.Resolve <IScope <Address> >());
                outer            = new PostUnhandledExceptionToUserTask(outer, cc.Resolve <IBotToUser>(), cc.Resolve <ResourceManager>(), cc.Resolve <TraceListener>());
                return(outer);
            })
            .As <IPostToBot>()
            .InstancePerLifetimeScope();

            builder
            .RegisterType <AlwaysSendDirect_BotToUser>()
            .AsSelf()
            .As <IBotToUser>()
            .InstancePerLifetimeScope();

            builder
            .RegisterType <DialogContext>()
            .As <IDialogContext>()
            .InstancePerLifetimeScope();
        }
 async Task IScorable <Score> .PostAsync <Item>(IPostToBot inner, Item item, object state, CancellationToken token)
 {
     await this.Scorable.PostAsync(inner, item, state, token);
 }
 public ScoringDialogTask(IPostToBot inner, IDialogStack stack, IScorable <IActivity, Score> scorable)
 {
     SetField.NotNull(out this.inner, nameof(inner), inner);
     SetField.NotNull(out this.stack, nameof(stack), stack);
     SetField.NotNull(out this.scorable, nameof(scorable), scorable);
 }
Exemple #19
0
 public SerializingDialogTask(IPostToBot inner, Address address, IScope <Address> scopeForCookie)
 {
     SetField.NotNull(out this.inner, nameof(inner), inner);
     SetField.NotNull(out this.address, nameof(address), address);
     SetField.NotNull(out this.scopeForCookie, nameof(scopeForCookie), scopeForCookie);
 }
Exemple #20
0
 public QueueDrainingDialogTask(IPostToBot inner, IBotToUser botToUser, IMessageQueue messageQueue)
 {
     SetField.NotNull(out this.inner, nameof(inner), inner);
     SetField.NotNull(out this.botToUser, nameof(botToUser), botToUser);
     SetField.NotNull(out this.messageQueue, nameof(messageQueue), messageQueue);
 }
Exemple #21
0
 public SetAmbientThreadCulture(IPostToBot inner)
 {
     SetField.NotNull(out this.inner, nameof(inner), inner);
 }
Exemple #22
0
        protected override void Load(ContainerBuilder builder)
        {
            base.Load(builder);

            builder.RegisterModule(new FiberModule <DialogTask>());

            // every lifetime scope is driven by a message

            builder
            .Register((c, p) => p.TypedAs <Message>())
            .AsSelf()
            .InstancePerMatchingLifetimeScope(LifetimeScopeTag);

            // components not marked as [Serializable]

            builder
            .RegisterType <ConnectorClientCredentials>()
            .AsSelf()
            .SingleInstance();

            builder
            .Register(c => new DetectEmulatorFactory(c.Resolve <Message>(), new Uri("http://localhost:9000"), c.Resolve <ConnectorClientCredentials>()))
            .As <IConnectorClientFactory>()
            .InstancePerLifetimeScope();

            builder
            .Register(c => c.Resolve <IConnectorClientFactory>().Make())
            .As <IConnectorClient>()
            .InstancePerLifetimeScope();

            builder
            .Register(c => new DetectChannelCapability(c.Resolve <Message>()))
            .As <IDetectChannelCapability>()
            .InstancePerLifetimeScope();

            builder
            .Register(c => c.Resolve <IDetectChannelCapability>().Detect())
            .As <IChannelCapability>()
            .InstancePerLifetimeScope();

            builder.RegisterType <MessageBackedStore>()
            .As <IBotDataStore>()
            .InstancePerLifetimeScope();

            builder
            .RegisterType <JObjectBotData>()
            .As <IBotData>()
            .InstancePerLifetimeScope();

            builder
            .Register(c => new BotDataBagStream(c.Resolve <IBotData>().PerUserInConversationData, BlobKey))
            .As <Stream>()
            .InstancePerLifetimeScope();

            builder
            .RegisterType <DialogTask>()
            .AsSelf()
            .As <IDialogStack>()
            .InstancePerLifetimeScope();

            builder
            .Register(c =>
            {
                var cc = c.Resolve <IComponentContext>();

                Func <IPostToBot> makeInner = () =>
                {
                    var task           = cc.Resolve <DialogTask>();
                    IDialogStack stack = task;
                    IPostToBot post    = task;
                    post = new ReactiveDialogTask(post, stack, cc.Resolve <IStore <IFiberLoop <DialogTask> > >(), cc.Resolve <Func <IDialog <object> > >());
                    post = new LocalizedDialogTask(post);
                    post = new ScoringDialogTask <double>(post, stack, cc.Resolve <IComparer <double> >(), cc.Resolve <ITraits <double> >(), cc.Resolve <IScorable <double>[]>());
                    return(post);
                };

                var outer = new PersistentDialogTask(makeInner, cc.Resolve <Message>(), cc.Resolve <IConnectorClient>(), cc.Resolve <IBotToUser>(), cc.Resolve <IBotData>());
                return(outer);
            })
            .As <IPostToBot>()
            .InstancePerLifetimeScope();

            builder
            .RegisterType <SendLastInline_BotToUser>()
            .AsSelf()
            .As <IBotToUser>()
            .InstancePerLifetimeScope();

            builder
            .RegisterType <DialogContext>()
            .As <IDialogContext>()
            .InstancePerLifetimeScope();
        }
Exemple #23
0
 public UnhandledExceptionHandler(IPostToBot inner, IBotToUser botToUser, TraceListener trace)
 {
     SetField.NotNull(out this.inner, nameof(inner), inner);
     SetField.NotNull(out this.botToUser, nameof(botToUser), botToUser);
     SetField.NotNull(out this.trace, nameof(trace), trace);
 }
Exemple #24
0
 public PassPostToBot(IPostToBot inner)
 {
     SetField.NotNull(out this.inner, nameof(inner), inner);
 }
        protected override void Load(ContainerBuilder builder)
        {
            base.Load(builder);

            builder.RegisterModule(new FiberModule <DialogTask>());

            // singleton components

            builder
            .Register(c => new ResourceManager("Microsoft.Bot.Builder.Resource.Resources", typeof(Resource.Resources).Assembly))
            .As <ResourceManager>()
            .SingleInstance();

            // every lifetime scope is driven by a message

            builder
            .Register((c, p) => p.TypedAs <IMessageActivity>())
            .AsSelf()
            .InstancePerMatchingLifetimeScope(LifetimeScopeTag);

            // components not marked as [Serializable]
            builder
            .RegisterType <MicrosoftAppCredentials>()
            .AsSelf()
            .SingleInstance();

            builder
            .RegisterType <BotIdResolver>()
            .As <IBotIdResolver>()
            .SingleInstance();

            builder
            .Register(c => new ConnectorClientFactory(c.Resolve <IMessageActivity>(), c.Resolve <MicrosoftAppCredentials>()))
            .As <IConnectorClientFactory>()
            .InstancePerLifetimeScope();

            builder
            .Register(c => c.Resolve <IConnectorClientFactory>().MakeConnectorClient())
            .As <IConnectorClient>()
            .InstancePerLifetimeScope();

            builder
            .Register(c => c.Resolve <IConnectorClientFactory>().MakeStateClient())
            .As <IStateClient>()
            .InstancePerLifetimeScope();

            builder
            .Register(c => new DetectChannelCapability(c.Resolve <IMessageActivity>()))
            .As <IDetectChannelCapability>()
            .InstancePerLifetimeScope();

            builder
            .Register(c => c.Resolve <IDetectChannelCapability>().Detect())
            .As <IChannelCapability>()
            .InstancePerLifetimeScope();

            builder.RegisterType <ConnectorStore>()
            .AsSelf()
            .InstancePerLifetimeScope();

            // If bot wants to use InMemoryDataStore instead of
            // ConnectorStore, the below registration should be used
            // as the inner IBotDataStore for CachingBotDataStore

            /*builder.RegisterType<InMemoryDataStore>()
             *  .AsSelf()
             *  .SingleInstance(); */

            builder.Register(c => new CachingBotDataStore(c.Resolve <ConnectorStore>(),
                                                          CachingBotDataStoreConsistencyPolicy.ETagBasedConsistency))
            .As <IBotDataStore <BotData> >()
            .AsSelf()
            .InstancePerLifetimeScope();

            builder
            .RegisterType <JObjectBotData>()
            .As <IBotData>()
            .InstancePerLifetimeScope();

            builder
            .Register(c => new BotDataBagStream(c.Resolve <IBotData>().PrivateConversationData, BlobKey))
            .As <Stream>()
            .InstancePerLifetimeScope();

            builder
            .RegisterType <DialogTask>()
            .AsSelf()
            .As <IDialogStack>()
            .InstancePerLifetimeScope();

            // Scorable implementing "/deleteprofile"
            builder
            .RegisterType <DeleteProfileScorable>()
            .As <IScorable <double> >()
            .InstancePerLifetimeScope();

            builder
            .Register(c =>
            {
                var cc = c.Resolve <IComponentContext>();

                Func <IPostToBot> makeInner = () =>
                {
                    var task           = cc.Resolve <DialogTask>();
                    IDialogStack stack = task;
                    IPostToBot post    = task;
                    post = new ReactiveDialogTask(post, stack, cc.Resolve <IStore <IFiberLoop <DialogTask> > >(), cc.Resolve <Func <IDialog <object> > >());
                    post = new ExceptionTranslationDialogTask(post);
                    post = new LocalizedDialogTask(post);
                    post = new ScoringDialogTask <double>(post, stack, cc.Resolve <IComparer <double> >(), cc.Resolve <ITraits <double> >(), cc.Resolve <IScorable <double>[]>());
                    return(post);
                };

                IPostToBot outer = new PersistentDialogTask(makeInner, cc.Resolve <IMessageActivity>(), cc.Resolve <IConnectorClient>(), cc.Resolve <IBotToUser>(), cc.Resolve <IBotData>());
                outer            = new PostUnhandledExceptionToUserTask(outer, cc.Resolve <IBotToUser>(), cc.Resolve <ResourceManager>(), cc.Resolve <TraceListener>());
                return(outer);
            })
            .As <IPostToBot>()
            .InstancePerLifetimeScope();

            builder
            .RegisterType <AlwaysSendDirect_BotToUser>()
            .AsSelf()
            .As <IBotToUser>()
            .InstancePerLifetimeScope();

            builder
            .RegisterType <DialogContext>()
            .As <IDialogContext>()
            .InstancePerLifetimeScope();
        }
Exemple #26
0
 public SerializeByConversation(IPostToBot inner, IAddress address, IScope <IAddress> scopeForCookie)
 {
     SetField.NotNull(out this.inner, nameof(inner), inner);
     SetField.NotNull(out this.address, nameof(address), address);
     SetField.NotNull(out this.scopeForCookie, nameof(scopeForCookie), scopeForCookie);
 }
Exemple #27
0
 public PersistentDialogTask(IPostToBot inner, IBotData botData)
 {
     SetField.NotNull(out this.inner, nameof(inner), inner);
     SetField.NotNull(out this.botData, nameof(botData), botData);
 }
Exemple #28
0
 public LogPostToBot(IPostToBot inner, IActivityLogger logger)
 {
     SetField.NotNull(out this.inner, nameof(inner), inner);
     SetField.NotNull(out this.logger, nameof(logger), logger);
 }
Exemple #29
0
 public SetAmbientThreadCulture(IPostToBot inner, ILocaleFinder localeFinder)
 {
     SetField.NotNull(out this.inner, nameof(inner), inner);
     SetField.NotNull(out this.localeFinder, nameof(localeFinder), localeFinder);
 }
Exemple #30
0
 async Task IScorable <double> .PostAsync <Item>(IPostToBot inner, Item item, object state, CancellationToken token)
 {
     this.stack.Fail(new OperationCanceledException());
     await this.stack.PollAsync(token);
 }