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

Botframework 如何在Microsoft bot应用程序中创建子线程或工作线程,botframework,Botframework,[Microsoft bot builder sdk] 如何在Microsoft bot应用程序中创建子线程或工作线程,该应用程序可以连续侦听第三方Web APi并将其发送给不同连接器上的用户 我创建了一个bot,并希望该bot能够持续监听第三方Web API。这项工作应该在单独的线程中完成。但若我在对话类中创建一个线程,它不会向用户发布响应,因为对话对象在等待用户输入时被挂起 [Serializable] public class SampleDialog : IDialog<objec

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

我创建了一个bot,并希望该bot能够持续监听第三方Web API。这项工作应该在单独的线程中完成。但若我在对话类中创建一个线程,它不会向用户发布响应,因为对话对象在等待用户输入时被挂起

[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);
        }
    }
[可序列化]
公共类示例对话框:IDialog
{
受保护整数计数=1;
[非串行化]
线程子任务;
公共异步任务StartAsync(IDialogContext上下文)
{           
ChildTask=新线程(新的参数化线程启动(RunChildTask));
ChildTask.Start(上下文);
Wait(MessageReceivedAsync);
}
私有void RunChildTask(对象上下文)
{
IDialogContext contex=作为IDialogContext的上下文;
while(true)
{
这个.count++;
contex.PostAsync($“{this.count++}:您说的来自child”);
睡眠(1000);
}
}
公共虚拟异步任务消息ReceivedAsync(IDialogContext上下文,IAwaitable参数)
{
var message=等待参数;
如果(message.Text==“重置”)
{
提示对话框。确认(
上下文
后重置异步,
“确实要重置计数吗?”,
“我不明白!”,
promptStyle:promptStyle.None);
}
其他的
{
wait context.PostAsync($“{this.count++}:您说的是{message.Text}”);
Wait(MessageReceivedAsync);
}
}

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

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

由于类实例不再具有引用,服务也不再具有引用。您刚刚启动的线程不再具有对服务的有效引用。因此,您有一个竞态条件,即在您启动的线程能够成功执行之前,chatbot的正常处理已完成。因为这是一个竞态条件,所以可能会出现以下情况:当线程变得幸运并发布消息时,当它只工作时可能会混淆。对于这种类型的任务,您应该考虑像VM上的云服务或Windows服务那样更持久的实现。