2016-12-01 2 views
1

Мой бот, который использует MS Bot Framework, застревает, отправляя сообщения пользователю в бесконечном цикле, как на каналах facebook, так и на emulator.MS Bot Framework застрял в отправке сообщений в бесконечном цикле

У моего бота есть «корень» IDialog, что-то вроде меню, которое вызывает несколько других IDialog s в зависимости от выбора пользователя. Дочерние Диалоги называются следующим образом:

 ... 
     else if (response.Text == MainOptions[2]) 
     { 
      await context.Forward(new InfoCounterDialog(), ChildDialogComplete, 
            response, CancellationToken.None); 
     } 
     ... 
  • response является IMessageActivity посланный пользователем;
  • ChildDialogComplete это метод, который строит главное меню снова и заканчивается следующими строками:

.

await context.PostAsync(restartPrompt); 
context.Wait(MainScreenSelectionReceived); 

Все диалоговые окна прекрасно работают, кроме этого очень мало диалога, который вызывает бесконечный цикл - бот не продолжает посылать это сообщение снова и снова, пока я остановить веб-приложение.

namespace XXXX 
{ 
[Serializable] 
public class InfoCounterDialog : IDialog 
{ 
    public async Task StartAsync(IDialogContext context) 
    { 
     var hourNow = DateTime.Now.Hour; 
     var openNow = ""; 
     if (hourNow >= 7) 
     { 
      openNow = "It is open now and will close at midnight."; 
     } 
     else 
     { 
      openNow = "It is closed now and will open at 7:00"; 
     } 
     var card = HeroCardUtils.CardWithImageAndMiscButtons(
      "Our information counter can help!", 
      "It's located in Shop 081, Level 3 in Building 2. " + openNow, 
      "http://www.[image URL here].jpg", 
      new[] { "More Details" }, 
      new[] { ActionTypes.OpenUrl }, 
      new[] { "[webpage URL here]" } 
      ); 
     await BotUtils.SendCardToChat(context, card); 
     context.Done(this); 
    } 
} 

}

Если вам интересно, что SendCardToChat делает:

public async static Task SendCardToChat(IDialogContext context, HeroCard card) 
    { 
     var activity = context.MakeMessage(); 
     activity.Attachments = HeroCardUtils.CardToAttachments(card); 
     await context.PostAsync(activity); 
    } 

Напомним:

  • Я запуская диалог из другого диалогового окна с помощью context.Forward()
  • Диалог supp osed показать сообщение пользователю и немедленно прекратить без дополнительного ввода от пользователя
  • Вместо этого он продолжает отправлять «Наш информационный счетчик может помочь!» сообщение бесконечно.

Мое лучшее предположение заключается в том, что дочерний диалог каким-то образом возвращает начальное сообщение пользователя в цепочку, что снова и снова запускает тот же диалог. Но этого не должно быть, ребенок IDialog не должен отправлять что-либо в разговор, кроме HeroCard, который я создал.

Или, может быть, я искал неправильное направление, и Bot Framework просто не поддерживает IDialog s, которые что-то делают и сразу заканчивают без context.Wait()?

+0

Есть у пробовали перемещения логики от StartAsync к методу типа MessageReceivedAsync? Вы делаете context.Forward, поэтому вам не нужно вводить логику в StartAsync ... –

+0

@EzequielJadib, поэтому вы подразумеваете 'StartAsync()' ничего не должны делать? Если ему нужно вызвать другой метод, я предполагаю, что вам нужно выполнить 'context.Wait()', и это означает, что вы ожидаете еще одного ввода от пользователя, чего я хочу избежать, и немедленно покажите сообщение. – K48

+0

Вам нужно сделать context.Wait(), но если вы делаете context.Forward, вы не будете ждать ввода пользователя, сообщение пройдет. Дайте мне знать, и я отправлю ответ –

ответ

1

Я обнаружил, что документации по контексту недостаточно. Done (значение R), но его действительно важно контролировать поток диалога.

Я предполагаю, что context.one (это) снова вызывает ваш диалог? вы пробовали

context.Done(true); 

Я нахожу это расстраивает, что это не метод context.Done() (без параметров), чтобы сказать, что диалог готовой.

В дополнение к этому, я нашел, что в this Microsoft Example они используют

// within a HotelsDialog.cs 
context.Done<object>(null); 

Это возможно потому, что они вызывают диалог с root dialog

// within RootDialog.cs 
context.Call(new HotelsDialog(), this.ResumeAfterOptionDialog); 
+0

Я решил проблему каким-то другим способом, хотя я не помню, как это сделать. Я продолжаю использовать context.Done (это) успешно в других проектах. Я предполагаю, что это объект IDialog, который мы завершаем. – K48

+0

В дополнение к этому, я начал использовать context.Done (null); аналогично утверждению finally в этом примере ms-класса https://github.com/Microsoft/BotBuilder-Samples/blob/master/CSharp/core-MultiDialogs/Dialogs/HotelsDialog.cs – chris31389

Смежные вопросы