EndDialogAsyn c Проблема Botframework V4 - PullRequest
1 голос
/ 02 мая 2020

У меня есть родительский диалог, который вызывает дочерний.
Фрагмент кода следующим образом.

    public Activity2MainDialog(UserState userState, string dialogMainId)
                    : base(dialogMainId)
            {
                InitialDialogId = Id;
                _studentProfileAccessor = userState.CreateProperty<StudentProfile>("studentProfile");

                WaterfallStep[] waterfallSteps = new WaterfallStep[]
                {
                    ActHardwareSetupStepAsync,
                    MsgWelcomeStepAsync,
                    QuestGoAheadStepAsync,
                    ReplyGoAheadStepAsync,
                    QuestWhatIsALedLedStepAsync,
                    ReplyWhatIsALedLedStepAsync,
                    QuestAcceptChallengeStepAsync,
                    ReplyAcceptChallengeStepAsync                    
                };

                // Add named dialogs to the DialogSet. These names are saved in the dialog state.
                AddDialog(new WaterfallDialog(dialogMainId, waterfallSteps));
                AddDialog(new TextPrompt(nameof(TextPrompt)));
                AddDialog(new ChoicePrompt(nameof(ChoicePrompt)));
                AddDialog(new ConfirmPrompt(nameof(ConfirmPrompt)));
            }
            private async Task<DialogTurnResult> ActHardwareSetupStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
            {            
                return await stepContext.BeginDialogAsync("environmentSetupDialog", "activity2MainDialog", cancellationToken);         
            }
private async Task<DialogTurnResult> MsgWelcomeStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            conversationSessionID = stepContext.Context.Activity.From.Id;
            conversationFromUser = stepContext.Context.Activity.Recipient.Name;
            var studentProfile = await _studentProfileAccessor.GetAsync(stepContext.Context, () => new StudentProfile(), cancellationToken);
            if (studentProfile.Name == null)
            {
                studentProfile.Name = "Usuario de Teste";
            }
            message = $"Oiii **{studentProfile.Name}!**";
            speakMessage = $"Oiii {studentProfile.Name}!";
            await SendMessage(message, BellaMain.SSMLWrap(speakMessage, "robot"), stepContext, cancellationToken);
            BellaMain.BotWait(message.Length.ToString());
            message = "Eu sou o Planck e estou aqui para ensinar a você um pouco mais sobre assuntos, digamos, habilidosos. ?";
            speakMessage = "Eu sou o Planck e estou aqui para ensinar a você um pouco mais sobre assuntos, digamos, habilidosos.";
            await SendMessage(message, BellaMain.SSMLWrap(speakMessage, "robot"), stepContext, cancellationToken);
            BellaMain.BotWait(message.Length.ToString());
            message = "Eu adoro construir robôs, drones e outras invenções tecnológicas. Espero que você também goste!";
            await SendMessage(message, BellaMain.SSMLWrap(message, "robot"), stepContext, cancellationToken);
            BellaMain.BotWait(message.Length.ToString());         
            return await stepContext.NextAsync(null, cancellationToken);
        }

Дочерний диалог выполняется хорошо, завершается, а затем возвращает поток диалога к родителю.
Фрагмент кода дочернего диалога ниже.

public class EnvironmentSetupDialog : ComponentDialog
    {
        private static BellaMain BellaMain = new BellaMain();        

        private static string message;
        private static string speakMessage;
        private static string invalidValueMessage;
        private static string conversationSessionID = "";
        private static string conversationFromUser = "";

        public EnvironmentSetupDialog(UserState userState, string dialogMainId)
                : base(dialogMainId)
        {
            InitialDialogId = Id;

            WaterfallStep[] waterfallSteps = new WaterfallStep[]
            {
                QuestStartupWordStepAsync,
                ReplyStartupWordStepAsync
            };

            // Add named dialogs to the DialogSet. These names are saved in the dialog state.
            AddDialog(new WaterfallDialog(dialogMainId, waterfallSteps));            
            AddDialog(new TextPrompt("startupWord", NamePromptValidatorAsync));                        
        }
        private async Task<DialogTurnResult> QuestStartupWordStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            message = "**CONFIGURAÇÃO DE AMBIENTE**";
            speakMessage = "CONFIGURAÇÃO DE AMBIENTE";
            await SendMessage(message, BellaMain.SSMLWrap(speakMessage, "robot"), stepContext, cancellationToken);

            //Changing message depending on calling dialog
            var callerActivityDialog = stepContext.Options.ToString().ToLower();
            switch (callerActivityDialog)
            {
                case "activity2maindialog":
                    message = "Clique no botão do microfone e fale a palavra mágica de hoje que é... XXX?";
                    speakMessage = "Clique no botão do microfone e fale a palavra mágica de hoje que é... XXX";
                    break;
                case "activity3maindialog":
                    message = "Hoje a palavra mágica é... YYY?";
                    speakMessage = "Hoje a palavra mágica é... YYY";
                    break;
            }
            LogMessage(message, stepContext, cancellationToken);
            invalidValueMessage = "A palavra mágica deve conter pelo menos 3 caracteres. Poderia falar novamente, por favor?";
            var promptOptions = new PromptOptions
            {
                Prompt = MessageFactory.Text(message,BellaMain.SSMLWrap(speakMessage, "robot")),
                RetryPrompt = MessageFactory.Text(invalidValueMessage, BellaMain.SSMLWrap(invalidValueMessage, "robot")),
            };
            return await stepContext.PromptAsync("startupWord", promptOptions, cancellationToken);

        }
        private static async Task<DialogTurnResult> ReplyStartupWordStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            stepContext.Values["startupWord"] = (string)stepContext.Result;
            return await stepContext.EndDialogAsync(null, cancellationToken);
        } 

Код BotWait:

public async Task<String> BotWait(string timespan)
        {
            var seconds = 0;
            double n;
            Task taskA = null;
            //Generates a time span based on the number of character of a given message
            if (double.TryParse(timespan, out n))
            {
                var timeRatio = 10;
                if (BellaMain.GlobalVariable.SpeedStyle == "normal")
                {
                    seconds = Convert.ToInt32(timespan) / timeRatio;
                }
                else //SpeedStyle == "fast"
                {
                    seconds = 1;
                }
            }
            //Generates a time span based on informed parameters
            else
            {
                if (BellaMain.GlobalVariable.SpeedStyle == "normal")
                {
                    switch (timespan)
                    {
                        case "bit":
                            seconds = 2;
                            break;
                        case "while":
                            seconds = 5;
                            break;
                        case "byte":
                            seconds = 7;
                            break;
                        case "brief":
                            seconds = 10;
                            break;
                        case "briefier":
                            seconds = 12;
                            break;
                        case "midbrief":
                            seconds = 15;
                            break;
                        case "midlongbrief":
                            seconds = 20;
                            break;
                        case "longbrief":
                            seconds = 25;
                            break;
                        case "long":
                            seconds = 40;
                            break;
                        case "longer":
                            seconds = 60;
                            break;
                        case "extralong":
                            seconds = 90;
                            break;
                        case "image":
                            seconds = 7;
                            break;
                        case "gif":
                            seconds = 10;
                            break;
                        case "carousel":
                            seconds = 50;
                            break;
                        case "video":
                            seconds = 60;
                            break;
                    }
                }
                else
                {
                    switch (timespan)
                    {
                        case "bit":
                            seconds = 1;
                            break;
                        case "while":
                            seconds = 1;
                            break;
                        case "byte":
                            seconds = 1;
                            break;
                        case "brief":
                            seconds = 1;
                            break;
                        case "briefier":
                            seconds = 1;
                            break;
                        case "midbrief":
                            seconds = 1;
                            break;
                        case "midlongbrief":
                            seconds = 1;
                            break;
                        case "longbrief":
                            seconds = 1;
                            break;
                        case "long":
                            seconds = 1;
                            break;
                        case "longer":
                            seconds = 1;
                            break;
                        case "extralong":
                            seconds = 1;
                            break;
                        case "image":
                            seconds = 1;
                            break;
                        case "gif":
                            seconds = 1;
                            break;
                        case "carousel":
                            seconds = 1;
                            break;
                        case "video":
                            seconds = 1;
                            break;
                    }
                }
            }
            taskA = Task.Run(() => Thread.Sleep(seconds * 1000));
            taskA.Wait();
            return null;
        }

Проблема: через несколько секунд появляется сообщение «Не удалось отправить повтор».
Я полагаю, что это связано с как я звоню / заканчиваю дочерний диалог.
Мысли о том, как это исправить?
Thx

1 Ответ

0 голосов
/ 08 мая 2020

Вызов BotWait без использования await. Когда BotWait завершит свою работу, пусть он отправит проактивное сообщение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...