Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 继续当前对话框的Microsoft Bot Framework主动消息_C#_Botframework - Fatal编程技术网

C# 继续当前对话框的Microsoft Bot Framework主动消息

C# 继续当前对话框的Microsoft Bot Framework主动消息,c#,botframework,C#,Botframework,Microsoft bot框架中有主动消息的概念-> 在我的解决方案中,我使用多个不同的对话框,在数据库中存储一些数据,每个回合都会加载这些数据。根据数据库中的数据,状态对象将被修改,根据修改情况,对话框将继续 在我的例子中,用户A启动对话框,系统以“我将您放入队列”响应,然后一段时间后B启动对话框,并询问他是否应与A配对。在用户B确认后,用户A的对话框应继续 我可以像下面这样给他写一条简单的消息,但我不知道如何简单地为匹配的用户强制一个新的“转向”,这样对话框就可以继续了 公共类基本bot:I

Microsoft bot框架中有主动消息的概念->

在我的解决方案中,我使用多个不同的对话框,在数据库中存储一些数据,每个回合都会加载这些数据。根据数据库中的数据,状态对象将被修改,根据修改情况,对话框将继续

在我的例子中,用户A启动对话框,系统以“我将您放入队列”响应,然后一段时间后B启动对话框,并询问他是否应与A配对。在用户B确认后,用户A的对话框应继续

我可以像下面这样给他写一条简单的消息,但我不知道如何简单地为匹配的用户强制一个新的“转向”,这样对话框就可以继续了

公共类基本bot:IBot
{
//一些性质
public BasicBot(CustomBotState botState、BotServices服务、UserState UserState、ConversationState ConversationState、ILoggerFactory loggerFactory、EndpointService EndpointService)
{
//设置一些属性
_conversationReferenceAccessor=_botState.CreateProperty(nameof(MatchConversationReference));
_dialogStateAccessor=_conversationState.CreateProperty(nameof(DialogState));
_matchStateAccessor=_userState.CreateProperty(nameof(MatchState));
var appId=string.IsNullOrWhiteSpace(endpointService.appId)?“1”:endpointService.appId;
Dialogs=新的DialogSet(_dialogStateAccessor);
添加(新的MatchDialog(_matchStateAccessor,loggerFactory,services,appId,_conversationReferenceAccessor));
}        
私有对话框集对话框{get;set;}
公共异步任务OnTurnAsync(ITurnContext turnContext,CancellationToken CancellationToken)
{
var dialogContext=await Dialogs.CreateContextAsync(turnContext);
if(turnContext.Activity.Type==ActivityTypes.Message)
{
var dialogResult=await dialogContext.ContinueDialogAsync();
如果(!dialogContext.Context.responsed)
{
var match=LoadMatchFromDatabase();
wait dialogContext.BeginDialogAsync(nameof(MatchDialog),match);
}
}
//保存对话、用户、机器人的状态
}
}
公共类匹配对话框:ComponentDialog
{
//一些性质
公共匹配对话框(IStatePropertyAccessor状态访问器、ILoggerFactory loggerFactory、BotServices服务、字符串appId、IStatePropertyAccessor(iMatchConversationPropertyAccessor)
:base(名称(匹配对话框))
{
//设置一些属性
var waterwallsteps=新的waterwallstep[]
{
初始化TestePasync,
WaitForAnswer,
};
AddDialog(新建WaterWallDialog(名称(匹配对话框),WaterWallSteps));
}
私有异步任务WaitForAnswer(WaterWallStepContext步骤,CancellationToken CancellationToken)
{
var otherUser=wait GetOtherUser(步骤);
var conversations=wait GetMatchConversion(steps.Context);
if(conversations.ContainsKey(otherUser.Identifier))
{
等待步骤.Context.Adapter.ContinueConversationAsync(AppId,conversations[otherUser.Identifier],
异步(turnContext,令牌)=>
{
Wait turnContext.SendActivityAsync($“为您找到某人”);
},
取消令牌);
}
}
专用异步任务初始化EstaTestePasync(WaterWallStepContext stepContext,CancellationToken CancellationToken)
{
var state=await StateAccessor.GetAsync(stepContext.Context,()=>null);
var match=stepContext。选项作为匹配项;
if(state==null)
{
wait StateAccessor.SetAsync(stepContext.Context,new MatchState(){Match=Match});
}
else if(state.Match==null | | Match.Id!=state.Match.Id)
{
state.Match=Match;
}
返回wait-stepContext.NextAsync();
}
}

}

有几种方法可以做到这一点,具体取决于您的代码。基本上,在发送发现用户B的主动消息的同一位置,您需要调用
dc.ContinueDialogAsync()
dc.repromtDialogAsync()
,如适用

话虽如此,我认为最好的选择是分割对话。一个对话框获取队列中的用户A。一旦进入,它们就不再处于对话框中。一旦找到用户B,它将向用户A发送新对话框

我通过以下方式或多或少地做到了这一点:

  • 创建在找到用户B后调用的对话框
  • CreateCallback()
    下(此示例在此处主动发送消息),我在该方法的末尾添加了以下代码(出于某些原因,它不希望格式化为代码):
  • Wait turnContext.SendActivityAsync($“作业{jobInfo.TimeStamp}已完成。”)

    var dc=await Dialogs.CreateContextAsync(turnContext)

    等待dc.BeginDialogAsync(名称(MyDialog))

    注意:为了测试,我在用户a“运行”作业后为他们创建了一个对话框。对话框一直在那里,直到用户B完成作业。之后立即为用户A启动了一个新对话框

    对您来说,这可能看起来像:

    //sample how I write something into the other conversation
    var conversations = await GetMatchConversion(steps.Context);
    if (conversations.ContainsKey(otherUser.Identifier))
    {
        await steps.Context.Adapter.ContinueConversationAsync(AppId, conversations[otherUser.Identifier],
               async (turnContext, token) =>
               {
                   // Send the user a proactive confirmation message.
                   await turnContext.SendActivityAsync($"{currentUser.Display()} I found a matching user...");
                   var dc = await Dialogs.CreateContextAsync(turnContext);
                   await dc.BeginDialogAsync(nameof(UserFoundDialog));
               },
               cancellationToken);
    }
    

    为了澄清这一点,UserA启动了一个对话框,在这个对话框中,用户被输入到一个队列中。当找到UserB并可以与UserA配对时,UserA会收到通知,表示已找到UserB。然后,您希望与UserA的对话继续。对吗?对,对。在我的例子中,用户A启动对话框,系统以“我将您放入队列”响应,然后一段时间后B启动对话框,并询问他是否应与A配对。在用户B确认后,用户A的对话框应继续。->我用这个简短的描述更新了描述。我已经有两个独立的对话框,一个QueueDialog和一个MatchDialog。我一直认为我需要用户状态o