2016-09-23 3 views
2

So habe ich diesen Dialog Kette, die ich wie so bin Aufruf ...Ärger mit Dialog Ketten

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

Der Dialog wie dieser

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

aussieht, wenn ich versuche, das ich zu laufen bekommen Zurück ein Fehler, der "Exception lautet: Microsoft.Bot.Builder.Internals.Fibers.ClosureCaptureException: anonyme Methodenverschlüsse, die die Umgebung erfassen, sind nicht serialisierbar, ziehen Sie in Betracht, die Umgebungserfassung zu entfernen, oder verwenden Sie ein Ersatzserialisierungs-Surrogat"

Kann mir jemand in die richtige Richtung zeigen? Ich bin mir nicht sicher, was ich hier falsch mache.

Antwort

3

Das Problem scheint mit der folgenden anonymen Methode zu sein:

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

Versuchen Sie sich mit einem Verfahren zu ersetzen, statt:

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

jedoch berücksichtigen, dass die Fortsetzungsverfahren werden wahrscheinlich nicht aufgerufen werden, bis Sie den GreetingDialog mit einem context.Done() "beenden".

+0

Omg vielen Dank! Das hat den Trick gemacht! – Matt