我有以下情况,我认为我做错了。
我有RootDialog
来调用ResultDialog
。 ResultDialog
向用户显示结果列表(使用HeroCard
)。
结果消息发布后,ResultDialog使用context.Done(..)
自行关闭。
在RootDialog- AfterResultDialog
Resume处理程序中,我想询问用户是否找到了匹配结果,使用另一个对话框(NotificationDialog
),但我希望在30秒后执行此操作。< / p>
经过一番研究,这似乎必须使用主动消息来完成。
通过此example,我找到了一种以主动方式发布NotificationDialog
的方法。
private async Task AfterResultDialog(IDialogContext context, IAwaitable<object> result)
{
var message = await result as IMessageActivity;
var conversationReference = context.Activity.ToConversationReference();
ConversationStarter.conversationReference = JsonConvert.SerializeObject(conversationReference);
t = new Timer(timerEvent);
t.Change(30000, Timeout.Infinite);
context.Wait<string>(NotificationDialogAfter);
}
public void timerEvent(object target)
{
t.Dispose();
ConversationStarter.Resume();
}
但我遇到的问题是,我对此NotifcationDialog
的结果感兴趣,知道用户下一步想要做什么。
但是我发现使用主动消息的所有示例都不会将主动消息的结果与对话框相关联:
public class ConversationStarter
{
public static string conversationReference;
public static async Task Resume()
{
var message = JsonConvert.DeserializeObject<ConversationReference>(conversationReference).GetPostToBotMessage();
var client = new ConnectorClient(new Uri(message.ServiceUrl));
using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, message))
{
var botData = scope.Resolve<IBotData>();
await botData.LoadAsync(CancellationToken.None);
var task = scope.Resolve<IDialogTask>();
// here it seems only to be possible to call a dialog using Void
var dialog = new NotificationDialog();
task.Call(dialog.Void<object, IMessageActivity>(), null);
await task.PollAsync(CancellationToken.None);
await botData.FlushAsync(CancellationToken.None);
}
}
}
NotificationDialogAfter
处理程序应根据用户输入决定下一个要调用的对话框:
private async Task NotificationDialogAfter(IDialogContext context, IAwaitable<string> result)
{
var whereToContinue = await result;
if (whereToContinue.Equals("Start over"))
{
context.ClearAllConversationDataKeys();
context.Call(new TagDialog(), this.TagDialogAfter);
}
else if (whereToContinue == "Tell friends")
{
context.Call(new TellFriendsDialog(), TellFriendsDialogAfter);
}
else if (whereToContinue == "Feedback")
{
context.Call(new FeedbackDialog(), this.FeedbackDialogAfter);
}
}
所以我基本上想要的是NotificationDialog
的结果被转发到Root对话框正在等待的NotificationDialogAfter
处理程序。
这甚至可能吗?
答案 0 :(得分:0)
我通过定义静态继续处理程序(在GlobalContinueHandler
中)来解决此问题,该静态处理程序可以在调用其他对话框时在NotificationDialog中提供。
[Serializable]
public class NotificationDialog : IDialog<string>
{
public Task StartAsync(IDialogContext context)
{
PromptDialog.Choice(context, Resume, new List<string> { "yes", "no" },
"Found what you're looking for?");
return Task.CompletedTask;
}
private async Task Resume(IDialogContext context, IAwaitable<string> result)
{
var message = await result;
if (message == "yes")
{
context.Call(new SignupDialog(), GlobalContinueHandler.SignupDialogAfter);
}
else
{
context.Call(new FeedbackDialog(), GlobalContinueHandler.FeedbackDialogAfter);
}
}
}
我真的不喜欢这种解决方案,但目前看来,它是可行的。