对话链的麻烦

时间:2016-09-23 20:26:04

标签: c# botframework

所以我有这个对话链,我这样称呼......

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);
    }
}

当我尝试运行它时,我得到一个错误,上面写着&#34;例外:Microsoft.Bot.Builder.Internals.Fibers.ClosureCaptureException:捕获环境的匿名方法闭包不可序列化,请考虑删除环境捕获或使用反射序列化代理&#34;

有人能指出我正确的方向吗?我不确定我在这里做错了什么。

1 个答案:

答案 0 :(得分:3)

问题似乎与以下匿名方法有关:

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}");
}

然而,考虑到在你&#34;结束&#34;之前,可能不会调用延续方法。带有context.Done()的GreetingDialog。