【问题标题】:Why context.Wait in StartAsync didn't stop the dialog为什么 StartAsync 中的 context.Wait 没有停止对话框
【发布时间】:2017-06-19 20:55:45
【问题描述】:

我确定这是个愚蠢的问题,但如果我不问我会更愚蠢 我有以下代码

    [Serializable]
public class RootDialog : IDialog<object>
{
    public async Task StartAsync(IDialogContext context)
    {
        await context.PostAsync("RootDialog !");

        context.Wait(MessageReceivedAsync);
    }

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

        // calculate something for us to return
        int length = (activity.Text ?? string.Empty).Length;

        // return our reply to the user
        await context.PostAsync($"You sent {activity.Text} which was {length} characters");

        context.Wait(MessageReceivedAsync);
    }
}

我理解语句上下文。Wait 用于等待用户的下一条消息。 但是如果我启动我的 RootDialog 我的声明 等待 context.PostAsync("RootDialog !"); 在我的声明之后执行 await context.PostAsync($"你发送的 {activity.Text} 是 {length} 个字符"); 也被执行了。

为什么?

为什么我没有在我的程序中暂停语句 context.Wait(MessageReceivedAsync); 在 StartAsync 函数中,就像我在 MessageReceivedAsync 函数中一样?

【问题讨论】:

  • 您使用的是什么版本的 BotBuilder?您如何创建/启动RootDialog?。顺便说一句,如果此对话框是使用 Conversation.SendAsync() 启动并在消息之后发生的,那么您所看到的行为就可以了。
  • 我使用我认为的最后一个版本。 3.8.是的,使用 Conversation.SendAsync

标签: c# botframework


【解决方案1】:

这里的文档中有一些关于 IDialogContext.Wait 的描述:https://docs.microsoft.com/en-us/bot-framework/dotnet/bot-builder-dotnet-dialogs#implementation-details

StartAsync 方法调用 IDialogContext.Wait 并继续 委托指定当一个新的时候应该调用的方法 收到消息 (MessageReceivedAsync)。

使用 BotBuilder SDK 构建的机器人是安静且无状态的,因为服务器本身不会跟踪或存储会话信息。 “context.Wait(method)”并不意味着“在这里冻结代码”,而是:下次有消息来自用户时,在对话框中的这个方法处继续。调用 next 的方法实际上是用对话框序列化并存储在State Service 中(见这里:Manage state data 最后一个 context.Wait(methodname) 将在用户下次在相同的上下文中发送消息时被调用对话。

一个例子可能有用:

[Serializable]
public class RootDialog : IDialog<object>
{
    public Task StartAsync(IDialogContext context)
    {
        context.Wait(MessageReceivedAsync);

        return Task.CompletedTask;
    }

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

        // calculate something for us to return
        int length = (activity.Text ?? string.Empty).Length;

        // return our reply to the user
        await context.PostAsync($"You sent {activity.Text} which was {length} characters");


        context.Wait(MessageReceivedAsync2);
    }

    private async Task MessageReceivedAsync2(IDialogContext context, IAwaitable<object> result)
    {
        await context.PostAsync($"Second MessageReceived");

        context.Wait(MessageReceivedAsync);
    }
}

上面的代码将为用户发送的每条消息在 MessageReceivedAsync 和 MessageReceivedAsync2 之间来回切换。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多