对话链的问题
本文关键字:问题 对话 | 更新日期: 2023-09-27 18:08:37
我把这个对话链命名为。
public static readonly IDialog<string> dialog = Chain.PostToChain()
.Select(msg => msg.Text)
.Switch(
new RegexCase<IDialog<string>>(new Regex("^hi", RegexOptions.IgnoreCase), (context, txt) =>
{
return Chain.ContinueWith(new GreetingDialog(),
async (ctx, res) =>
{
var token = await res;
var name = "User";
context.UserData.TryGetValue<string>("Name", out name);
return Chain.Return($"You are logged in as: {name}");
});
}),
new DefaultCase<string, IDialog<string>>((context, txt) =>
{
int count;
context.UserData.TryGetValue("count", out count);
context.UserData.SetValue("count", ++count);
string reply = string.Format("{0}: You said {1}", count, txt);
return Chain.Return(reply);
}))
.Unwrap()
.PostToUser();
对话框如下图
[Serializable]
public class GreetingDialog : IDialog
{
public async Task StartAsync(IDialogContext context)
{
await context.PostAsync("Hi I'm John Bot");
context.Wait(MessageReceivedAsync);
}
public async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> argument)
{
var message = await argument;
var userName = String.Empty;
var getName = false;
context.UserData.TryGetValue<string>("Name", out userName);
context.UserData.TryGetValue<bool>("GetName", out getName);
if (getName)
{
userName = message.Text;
context.UserData.SetValue<string>("Name", userName);
context.UserData.SetValue<bool>("GetName", false);
}
if (string.IsNullOrEmpty(userName))
{
await context.PostAsync("What is your name?");
context.UserData.SetValue<bool>("GetName", true);
}
else
{
await context.PostAsync(String.Format("Hi {0}. How can I help you today?", userName));
}
context.Wait(MessageReceivedAsync);
}
}
当我尝试运行这个时,我得到一个错误,说"异常:Microsoft.Bot.Builder.Internals.Fibers.ClosureCaptureException:捕获环境的匿名方法闭包是不可序列化的,考虑删除环境捕获或使用反射序列化代理"
谁能给我指个正确的方向?我不知道我哪里做错了。问题似乎与以下匿名方法有关:
async (ctx, res) =>
{
var token = await res;
var name = "User";
context.UserData.TryGetValue<string>("Name", out name);
return Chain.Return($"You are logged in as: {name}");
});
试着用一个方法代替:
return Chain.ContinueWith(new GreetingDialog(), AfterGreetingContinuation);
private async static Task<IDialog<string>> AfterGreetingContinuation(IBotContext context, IAwaitable<object> res)
{
var token = await res;
var name = "User";
context.UserData.TryGetValue<string>("Name", out name);
return Chain.Return($"You are logged in as: {name}");
}
但是,要考虑到延续方法可能不会被调用,直到您使用context.Done()"结束"greingdialog。