2016-12-01 100 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服務。

相關問題