villasv
villasv

Reputation: 6841

BotBuilder async counter implementation with Task not working

I'm trying to make my Bot more fluid by holding a response until the messages become sparse.

My idea was simple: every time I receive a message, I spawn a delayed task to inform the future me whether I should respond the recent activity or not.

using System;
using System.Threading.Tasks;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Connector;

namespace GupyInterviewBot.Dialogs
{
    [Serializable]
    public class InterviewDialog : IDialog<object>
    {
        private int _patience = 0;

        public async Task StartAsync(IDialogContext context)
        {
            _patience = 0;
            context.Wait(PatientReadAsync);
        }

        public async Task PatientReadAsync(IDialogContext context, IAwaitable<IActivity> awaitable)
        {
            var activity = await awaitable;
            if (activity.Type == ActivityTypes.Message)
            {
                HoldOn();
                context.Wait(PatientReadAsync);
            }
            else
            {
                await context.PostAsync("My patience is running out: " + _patience);
                context.Wait(PatientReadAsync);
            }
        }

        private void HoldOn(int seconds = 3)
        {
            Task.Run(async () =>
            {
                _patience += 1;
                await Task.Delay(seconds * 1000);
                _patience -= 1;
            });
        }
    }
}

The thing is, the _patience counter is only increasing and never decreasing I have no idea why. I posted this question without mentioning the framework, but after trying to find a MWE with a Console Application everything worked. Now I believe there's something related to the way the framework preserves state, but I'm not sure.

You can attest that _patience is only increasing by sending a few messages and then send some Ping activities in the Bot Emulator.

Upvotes: 1

Views: 309

Answers (1)

sellotape
sellotape

Reputation: 8325

Change your code to this:

private async Task HoldOnAsync(int seconds = 3)
{
    _patience += 1;
    await Task.Delay(seconds * 1000);
    _patience -= 1;
}

and change

HoldOn();

to

await HoldOnAsync();

Task.Run() just queues the task and returns immediately. So it's probably working but your increments are winning the race.

Upvotes: 1

Related Questions