2017-05-12 4 views
0

Ich mache einen proaktiven Bot mit dem Wiederaufnahme-Cookie.Bot Framework mit Singleton Klasse

Ich habe 1 Singleton-Klasse, die eine Liste von Objekten ist.

public static MyObj instance = new MyObj(); 

public List<Objects> thename = null; 
public int count { get; set; } 

public static MyObj Instance 
{ 
     get 
     { 
      return instance; 
     } 
} 

dann habe ich die conversationStarter Klasse: wo ich die Singleton wie definiert haben

public class ConversationStarter 
    { 

     public static string resumptionCookie; 

     public static async Task Resume() 
     { 
      var message = ResumptionCookie.GZipDeserialize(resumptionCookie).GetMessage(); 
      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>(); 

       //interrupt the stack 
       var dialog = new AlarmDialog(); 
       task.Call(dialog.Void<object, IMessageActivity>(), null); 


       task.PollAsync(CancellationToken.None); 

       //flush dialog stack 
       await botData.FlushAsync(CancellationToken.None); 
      } 
     } 
    } 
} 

Vom RootDialog ich einen Timer haben, dass ein neuer Dialog alle x Sekunden nennen. In diesem Dialog ich tun:

[Serializable] 
    public class NewDialog : IDialog<object> 
    { 
     public Myobj objList; 

     public async Task StartAsync(IDialogContext context) 
     { 
      objList= Myobj.Instance; 


      PromptDialog.Choice(context, this.AfterSelectOption, 
       new string[] { "Stay in this survey", "Get back to where I was" }, 
       "Hello, you're in the survey dialog. Please pick one of these options"); 

     } 

     private async Task AfterSelectOption(IDialogContext context, IAwaitable<string> result) 
     { 

      if ((await result) == "Get back to where I was") 
      { 
       await context.PostAsync("Great, back to the original conversation!"); 
       context.Done(String.Empty); //Finish this dialog 
      } 
      else 
      { 
       await context.PostAsync("I'm still on the survey until you tell me to stop"); 
       PromptDialog.Choice(context, this.AfterSelectOption, new string[] { "Stay in this survey", "Get back to where I was" }, "Hello, you're in the survey dialog. Please pick one of these options"); 

      } 
     } 
    } 
} 

Wenn ich Zugriff auf die Instanz von MyObj im NewDialog ich bin die folgende Ausnahme int ConversationStarter bekommen:

Microsoft.Bot.Builder.Internals.Fibers.InvalidNeedException: 'invalid need: expected Wait, have None' 

an der Linie:

task.PollAsync(CancellationToken.None); 

Wenn ich nicht versuche, auf meine Singleton-Klasse zuzugreifen, läuft alles reibungslos. Ist es nicht möglich, eine Singleton-Klasse wie diese zu verwenden?

+0

Ist Ihre Singleton-Klasse serialisierbar? –

+0

Es ist serialisierbar – JoaoFilipeClementeMartins

+0

Haben Sie dieses Beispiel ausgecheckt: https://github.com/MicrosoftDX/botFramework-proactiveMessages –

Antwort

0

Dies ist nicht die Art, einen pro-aktiven Bot zu implementieren. Wenn ich mich nicht täusche, indem ich die PollAsync-Methode aufruft, unterbricht man den Dialogstapel, ohne ihm einen Punkt zu geben, von dem aus er fortgesetzt werden kann.

Ich denke, Sie sollten sich this example ansehen. Es hat das gleiche Ziel wie Ihr Bot, aber es verwendet Autofac. Genauer gesagt die ExternalEvents Klasse. Die Verwendung eines IOC-Containers ist auch besser als die Implementierung eines Singleton.