2016-12-01 82 views
-1

[Microsoft bot builder sdk] 如何在Microsoft bot应用程序中创建子线程或辅助线程,该应用程序可以不断侦听第三方Web APi并发布消息给不同连接器上的用户。如何在Microsoft bot应用程序中创建子线程或工作线程

我创建了一个bot,并希望该bot能够不断收听第三方Web API。这项工作应该在一个单独的线程中完成。但是,如果我在Dialog类中创建线程,它不会向用户发布响应,因为对话框对象在等待用户输入时被暂停。

[Serializable] 
public class SampleDialog : IDialog<object> 
{ 
    protected int count = 1; 
    [NonSerialized] 
    Thread ChildTask; 
    public async Task StartAsync(IDialogContext context) 
    {   
     ChildTask = new Thread(new ParameterizedThreadStart(RunChildTask)); 
     ChildTask.Start(context); 
     context.Wait(MessageReceivedAsync); 
    } 

    private void RunChildTask(object context) 
    { 
     IDialogContext contex = context as IDialogContext; 
     while (true) 
     { 
      this.count++; 
      contex.PostAsync($"{this.count++}: You said From child"); 
      Thread.Sleep(1000); 
     } 
    } 

    public virtual async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> argument) 
    { 
     var message = await argument; 
     if (message.Text == "reset") 
     { 
      PromptDialog.Confirm(
       context, 
       AfterResetAsync, 
       "Are you sure you want to reset the count?", 
       "Didn't get that!", 
       promptStyle: PromptStyle.None); 
     } 
     else 
     { 
      await context.PostAsync($"{this.count++}: You said {message.Text}"); 
      context.Wait(MessageReceivedAsync); 
     } 
    } 

RunChildTask方法被调用但不回发给用户。

回答

0

它不工作的原因是由于聊天机器人的技术特性。聊天机器人使用ASP.NET Web API,它与所有其他Web应用程序(例如WebForms或MVC)一样是无状态的。这意味着请求从客户端(在这种情况下为Bot连接器)到达,请求由您的聊天机器人处理,聊天机器响应,并且聊天机器人的类实例成为垃圾收集的资格。当下一个请求进入时,它会为您的chatbot创建另一个Web API实例。

由于类实例不再有引用,所以服务也没有。您刚刚启动的线程不再具有对服务的有效引用。因此,您有一个竞争条件,即在您启动的线程可以成功执行之前,chatbot的正常处理完成。因为这是一种竞争条件,所以有时候线程很幸运并且发布了一条消息,这可能会让人感到困惑。对于这种类型的任务,您应该考虑一个更持久的实现,例如VM上的云服务或Windows服务。

相关问题