如何向对话框发送消息导致"堆栈为空"例外?

时间:2017-03-16 21:58:36

标签: autofac botframework

在Azure上托管的我的(非Luis)僵尸程序应用程序有一个RootDialog,它可以处理所有传入的活动,这些活动不是可以直接在MessagesController.Post中处理的简单命令,因此:

var dialog = scope.Resolve<IDialog<object>>();
await Conversation.SendAsync(activity, () => dialog);

RootDialog实现IDialog<object>,并在Autofac中注册。它在标准的Conversation.Container生命周期范围内得到解决。

我还有一个WebJob,它的工作是偶尔重置堆栈(杀死任何当前活动的对话框)并启动一个新的对话框,它本身可以调用其他对话框。我们称他们为DialogProactive:IDialog<object>DialogChild:IDialog<bool>

首先,重置堆栈。 &#39;消息&#39;是从保存在数据库中的ResumptionCookie获得的。

using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, message))
{
    var botData = scope.Resolve<IBotData>();
    await botData.LoadAsync(default(CancellationToken));
    var stack = scope.Resolve<IDialogStack>();
    stack.Reset();
    await botData.FlushAsync(default(CancellationToken));
    await userInfo.ResetUserStateDBAsync();
}

然后由bot发起一个对话框:

using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, message))
{
     var botData = scope.Resolve<IBotData>();
     await botData.LoadAsync(default(CancellationToken));

     var stack = scope.Resolve<IDialogTask>();
     IDialog<object> dialog = null;

     dialog = scope.ResolveNamed<IDialog<object>>("ProactiveDialog",
                                        new NamedParameter("Param1", p1),
                                        new NamedParameter("dialogName", "DialogChild));

     stack.Call(dialog.Void<object, IMessageActivity>(), null);
     await stack.PollAsync(CancellationToken.None);
     await botData.FlushAsync(CancellationToken.None);
 }

ProactiveDialogA解析IComponentContext并继续解析并在其自己的StartAsync中调用DialogChild:

....
context.Call(newDialogChild, this.DialogDone);

此DialogChild会调用context.Done(true),因此ProactiveDialog的DialogDone会自动调用&#39; true&#39;结果。它本身调用context.Done(null),一切都已完成。

但是下次用户向僵尸程序发送消息时,RootDialog会尝试处理它(请参阅上面的问题的开头),Conversation.SendAsync(...)失败并出现InvalidOperationException - Stack为空(并且所以用户看到了“对不起,我的机器人代码有问题。”#);

之后很好 - 我假设发生了某种内部重置。

这是为什么?我以为我们会回到起点,并且会创建一个新的RootDialog并将其放在空堆栈上。为什么这个例外?

是否与WebJob中使用的ResumptionCookie在机器人启动的对话框完成后与后续交互不同步?

使用3.5.3。感谢。

0 个答案:

没有答案