【问题标题】:Fix infinite loop when asking the user to enter a data修复要求用户输入数据时的无限循环
【发布时间】:2022-09-23 14:09:30
【问题描述】:

我需要帮助,我正在创建一个允许输入日期的机器人,我需要验证用户是否输入了相应的日期,否则它会返回并要求他输入日期。

当我这样做时,它会在模拟器中执行机器人时引发无限循环

  public PruebaOpciones()
    {
        var waterfallStep = new WaterfallStep[]
       {
           SetPeriodo,
           Confirmation,
           FinalProcess
       };
        AddDialog(new WaterfallDialog(nameof(WaterfallDialog), waterfallStep));
        AddDialog(new TextPrompt(nameof(TextPrompt)));
    }

    private async Task<DialogTurnResult> SetPeriodo(WaterfallStepContext stepContext, CancellationToken cancellationToken)
    {
      
        while (true)
        {
            string periodo = \"Ingresa el mes que quieres consultar por favor.\";
            await stepContext.PromptAsync(
                           nameof(TextPrompt),
                           new PromptOptions
                           {
                               Prompt = MessageFactory.Text(periodo),
                           },
                           cancellationToken
                           );
            periodo = periodo.ToLower();
        int periodoLength = periodo.Length;
        if (periodoLength == 1)
        {
                periodo = \"0\" + periodo;
                break;  
        }
        string[] periodoList = { \"enero\", \"febrero\", \"marzo\", \"abril\",\"mayo\",\"junio\",\"julio\",\"agosto\",\"septiembre\",\"octubre\",
        \"noviembre\",\"diciembre\",\"01\", \"02\", \"03\", \"04\", \"05\",\"06\",\"07\",\"08\",\"09\",\"10\",\"11\",\"12\"};
        List<string> periodoRange = new List<string>(periodoList);
            
            if (periodoRange.Contains(periodo))
            {

                break;
            }
            else
            {
                return await SetPeriodo(stepContext, cancellationToken);
            }
           
        }

        return await stepContext.ContinueDialogAsync(cancellationToken: cancellationToken);
    }

enter image description here

[1]: https://i.stack.imgur.com/CIb4s.png

我怎样才能解决这个问题,而不是给我一个无限循环,只问我一次,如果我输入错误,回来问我?

  • 永远不要使用 while true ......在循环中放入一些东西以使其在 while 上停止
  • 您是否在调试器中设置了程序并输入了您期望应该跳出循环的值。当您逐步执行您的程序时,会发生什么?你们中的一个测试是否按照您期望的方式运行。 while (true) { } 没有任何问题,但您可以确保不会卡在那里

标签: c# bots botframework


【解决方案1】:

我对机器人框架一无所知,但是对stepContext.PromptAsync 的调用实际上最终会改变periodo 的值吗?我不这么认为。我认为您需要检查调用的返回值(请参阅:DialogContext.PromptAsync

我相信发生的事情是您将periodo 设置为提示字符串,显示一个对话框以获取用户的输入,然后将提示字符串与有效月份进行比较。当然,这会失败,您最终会陷入无限循环。

此外,这里还有一些其他的一般性意见:

  1. 您无需在每次迭代时重新创建月份列表。而是在循环外创建一次。与提示文本相同。
  2. 您无需创建数组即可创建列表 - 只需直接创建列表即可。
  3. 在将0 添加到periodo 时,您似乎跳出了if 语句的while 循环。这似乎是一个逻辑错误。
  4. 在单独的变量中捕获periodo 的长度属性是没有意义的。
  5. 在循环体结束时,所有代码路径都会返回一些内容(return 将结束循环),因此它实际上不会循环。在输入错误的情况下,它会递归调用相同的方法。我们可以删除else 并让循环重新运行,而不是再次调用该方法。

    下面是一些解决上述 cmets 和可能解决您的问题。真正了解机器人框架以及如何检索用户输入的人,希望能纠正这个问题或给你一个更好的答案。


    private async Task<DialogTurnResult> SetPeriodo(WaterfallStepContext stepContext, 
        CancellationToken cancellationToken)
    {
        string prompt = "Ingresa el mes que quieres consultar por favor.";
    
        List<string> periodoRange = new List<string> {
            "enero", "febrero", "marzo", "abril", "mayo", "junio", "julio", "agosto",
            "septiembre", "octubre", "noviembre", "diciembre", "01", "02", "03", "04",
            "05", "06", "07", "08", "09", "10", "11", "12" };
    
        while (true)
        {
            await stepContext.PromptAsync(
                nameof(TextPrompt),
                new PromptOptions { Prompt = MessageFactory.Text(prompt) },
                cancellationToken);
    
            // Capture the value entered by the user - I'm not exactly sure
            // how to get this, but from the documentation it sounds like 
            // it would look something like this:
            string periodo = ((string)stepContext.Values["periodo"]).ToLower();
    
            if (periodo.Length == 1)
            {
                periodo = "0" + periodo; 
            }
            
            if (periodoRange.Contains(periodo))
            {
                return await stepContext.ContinueDialogAsync(
                    cancellationToken: cancellationToken);
            }       
        }
    }
    

【讨论】:

    猜你喜欢
    • 2019-02-01
    • 2020-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-20
    • 2015-04-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多