如何在Microsoft bot应用程序中创建子线程或工作线程

时间:2016-12-01 14:09:33

标签: botframework

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

我创建了一个机器人,并希望该机器人不断收听第三方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方法但不回发给用户。

1 个答案:

答案 0 :(得分:0)

它无法工作的原因是因为实现了聊天机器人的技术的性质。聊天机器人使用ASP.NET Web API,它像所有其他Web应用程序(例如WebForms或MVC)一样是无状态的。这意味着请求从客户端(在本例中为Bot Connector)到达,请求由聊天机器人处理,聊天机器人响应,聊天机器人的类实例有资格进行垃圾回收。当下一个请求进入时,它会为您的聊天机器人创建另一个Web API实例。

由于类实例不再具有引用,因此服务也不会。您刚刚启动的线程不再具有对服务的有效引用。因此,您有一个竞争条件,聊天机器人的正常处理在您启动的线程成功执行之前完成。因为它是一种竞争条件,所以有时候线程会幸运并发布一条消息,当它有时只能工作时可能会令人困惑。对于此类任务,您应该考虑更持久的实现,例如VM上的云服务或Windows服务。