1

首先,我必须将电话号码作为用户输入,然后我需要调用 qnadialog 直到用户退出。以下是我的代码:

public class RootDialog : IDialog<object>
{
    private string phoneNo;
    public async Task StartAsync(IDialogContext context)
    {
        context.Wait(this.MessageReceivedAsync);
    }

    private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<object> result)
    {
        var activity = await result;

        await this.SendWelcomeMessageAsync(context);
    }
    private async Task SendWelcomeMessageAsync(IDialogContext context)
    {
        if (string.IsNullOrEmpty(phoneNo))
        {
            await context.PostAsync("Hi, I'm Anna. Let's get started.");
            context.Call(new PhoneNoDialog(), this.PhoneNoDialogResumeAfter);
        }
        else
        {
            await context.Forward(new SimpleQnADialog(), ResumeAfterSimpleQnADialog, context.Activity, CancellationToken.None);                
        }
    }
    private async Task PhoneNoDialogResumeAfter(IDialogContext context, IAwaitable<string> result)
    {
            this.phoneNo = await result;
            await context.PostAsync($"Thank you for the information. How can I help you?");
            context.Wait(this.MessageReceivedAsync);
    }

    private async Task ResumeAfterSimpleQnADialog(IDialogContext context, IAwaitable<object> result)
    {
            context.Done<object>(null);            
    }
}

PhoneNoDialog.cs

public class PhoneNoDialog : IDialog<string>
{
    private int attempts = 3;

    public async Task StartAsync(IDialogContext context)
    {
        await context.PostAsync("Please enter your phone no");

        context.Wait(this.MessageReceivedAsync);
    }

    private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
    {
        var message = await result;

        if ((message.Text != null) && (message.Text.Trim().Length > 0))
        {
            context.Done(message.Text);
        }
        else
        {
            --attempts;
            if (attempts > 0)
            {
                await context.PostAsync("I'm sorry, I don't understand your reply. What is your phone no?");
                context.Wait(this.MessageReceivedAsync);
            }
            else
            {
                context.Fail(new TooManyAttemptsException("Message was not a string or was an empty string."));
            }
        }
    }
}

SimpleQnADialog.cs

[QnAMaker("subkey", "kbid")]
public class SimpleQnADialog : QnAMakerDialog
{

}

如果我使用 QnAmaker 创建独立机器人,一切正常,但如果我以上述方式调用上下文,则它不会按预期工作。我不确定我哪里出了问题。而且,很多时候机器人模拟器会给出意想不到的异常。

4

1 回答 1

1

当您实施此操作时,您正在尝试RootDialog在 QnA 收到回复后完成您的操作:

private async Task ResumeAfterSimpleQnADialog(IDialogContext context, IAwaitable<object> result)
{
        context.Done<object>(null);            
}

事实上,一旦 QnAMakerDialog 尝试回答,它就会完成,您可以在此处查看其来源。

如果你想循环提问,你应该再次调用等待:

private async Task ResumeAfterSimpleQnADialog(IDialogContext context, IAwaitable<object> result)
{
    context.Wait(this.MessageReceivedAsync);
}
于 2018-03-15T15:43:16.760 回答