已调用 ResumeAfter 方法,但未在下一个对话框中调用 context.done

ResumeAfter method is already called without calling context.done in the next dialog

我实现了一个首先启动 QnA 对话框的结构。如果 QnA 对话框无法解决问题,那么它会启动一个定义了一些主要功能的 Luis 对话框。基于这些主要功能,我启动了可以解决问题的特定对话框。

我的问题是,当我尝试从 QnAMaker 启动 LuisDialog 时,它会启动另一个 LuisDialog 以进行对话,该对话框不会使用 wait 方法停止,并在执行后立即自动调用 ResumeAfter 方法。

QnADialog:

protected override async Task RespondFromQnAMakerResultAsync(IDialogContext context, IMessageActivity message, QnAMakerResults results)
{
    if (results == null || results.Answers.Count==0 || !IsConfidentAnswer(results) || results.Answers.FirstOrDefault().Score<0.75) {
        await context.Forward(new MainLuisDialog(), MessageReceived, context.Activity.AsMessageActivity(), CancellationToken.None);

    }
}

第一个 Luis 对话:

[LuisIntent(ErrorFileLink)]
public async Task ErrorFileLinkIntentHandler(IDialogContext context, LuisResult result) {
    await context.Forward(new ErrorFileLinkDialog(), CallBackHandler, context.Activity.AsMessageActivity(), CancellationToken.None);
}

private async Task CallBackHandler(IDialogContext context, IAwaitable<object> result)
{
    try {
        var returnedResult = await result;
        if (returnedResult as string == "done")
            context.Done(false);
    }
    catch (Exception e) {
    }
}

第二次路易斯对话:

[LuisIntent(MainAppIntent)]
public async Task MainAppIntentHandler(IDialogContext context, LuisResult result)
{
    if(context.GetPrivateConversationData<SyncIssueStates>(CurrentDialogState) == SyncIssueStates.ExpectingSyncCompleteMessage)
    {
        await context.PostAsync(Utility.GetResourceString("SYNC_ISSUE_PLEASE_WAIT_SYNC_COMPELTE"));
        context.Wait(MessageReceived);
        return;
    }
    await context.PostAsync(Utility.GetResourceString("SYNC_ISSUE_GET_ERROR_MESSAGE"));
    context.SetPrivateConversationData(CurrentDialogState, SyncIssueStates.ExpectingErrorMessage);
    context.Wait(MessageReceived);
}

执行 Forward 后立即调用 First Luis Dialog 中的 CallBackHandler 方法。

我认为此行为是由于 QnAMakerDialogDefaultWaitNextMessageAsync 方法中调用了 context.Done(true);。参考:https://github.com/Microsoft/BotBuilder-CognitiveServices/blob/master/CSharp/Library/QnAMaker/QnAMaker/QnAMakerDialog.cs#L203

尝试改写 DefaultWaitNextMessageAsync 方法:

protected override async Task DefaultWaitNextMessageAsync(IDialogContext context, IMessageActivity message, QnAMakerResults results)
{
    if (results == null || results.Answers.Count == 0 || !IsConfidentAnswer(results) || results.Answers.FirstOrDefault().Score < 0.75)
    {
        await context.Forward(new FirstDialog(), AfterForward, context.Activity.AsMessageActivity(), CancellationToken.None);
        context.Wait(base.MessageReceivedAsync);
    }
    else
    {
        await base.DefaultWaitNextMessageAsync(context, message, results);
    }
}