2016-11-18 60 views
1

所以我有這樣的對話,我創建:執行馬上行動

[Serializable] 
public class StepOneDialog : IDialog<object> 
{ 

    // Private fields 
    protected readonly IList<GroupResponseModel> _groups; 
    protected readonly GroupResponseModel _group; 
    protected readonly int _currentStep; 
    protected int _currentQuestion = 0; 

    /// <summary> 
    /// Default constructor 
    /// </summary> 
    /// <param name="groups">The question groups</param> 
    public StepOneDialog(IList<GroupResponseModel> groups, int step) 
    { 
     _groups = groups; 
     _group = groups[step]; 
     _currentStep = step; 
    } 

    /// <summary> 
    /// Start our response 
    /// </summary> 
    /// <param name="context">The current context</param> 
    /// <returns></returns> 
    public async Task StartAsync(IDialogContext context) => context.Wait(AskQuestion); 

    /// <summary> 
    /// When our message is recieved we execute this delegate 
    /// </summary> 
    /// <param name="context">The current context</param> 
    /// <param name="result">The result object</param> 
    /// <returns></returns> 
    private async Task AskQuestion(IDialogContext context, IAwaitable<IMessageActivity> result) 
    { 

     // Get our question and answers 
     var question = this._group.Questions[_currentQuestion]; 
     var questionText = question.Text; 
     var answers = question.Answers.Select(m => m.Text).ToList(); 
     var options = new PromptOptions<string>(questionText, options: answers); 

     // If wer are the first question AND we have more than 1 question, Post the question header 
     if (_currentQuestion == 0 && _group.Questions.Count > 1) 
      await context.PostAsync(_group.Text); 

     // Ask our question 
     Choice<string>(context, GetAnswer, options); 
    } 

    /// <summary> 
    /// Get our answer and decide what to do next 
    /// </summary> 
    /// <param name="context">The current context</param> 
    /// <param name="result">The answer text</param> 
    /// <returns></returns> 
    private async Task GetAnswer(IDialogContext context, IAwaitable<string> result) 
    { 

     // Get our quest 
     var questions = _group.Questions; 
     var length = questions.Count; 
     var question = _group.Questions[_currentQuestion]; 

     // Assign our answer to our question 
     foreach (var answer in question.Answers) 
      if (answer.Text == await result) 
       question.Answer = answer; 

     // Increase our index 
     _currentQuestion++; 

     // If our current index is greater or equal than the length of the questions 
     if (_currentQuestion == length) 
     { 

      // If our step is the same as our group length 
      var groupLength = _groups.Count - 1; 

      // If we have reached the end of our steps, this dialog is done 
      if (groupLength == _currentStep) 
       context.Wait(ResumeAfter); 

      // Otherwise, got to the next step 
      await context.Forward(new StepOneDialog(_groups, _currentStep + 1), ResumeAfter, new Activity { }, CancellationToken.None); 

     // Otherwise, ask our next question 
     } else 
      context.Wait(AskQuestion); 
    } 

    /// <summary> 
    /// When the child dialog has complete, mark this as done 
    /// </summary> 
    /// <param name="context">The current context</param> 
    /// <param name="result">The result object</param> 
    /// <returns></returns> 
    private async Task ResumeAfter(IDialogContext context, IAwaitable<object> result) => context.Done(this); 
} 

有3個步驟,所以當第一步開始提出問題。當用戶回答問題時(因爲第一步中只有1個問題),一個新的對話實例被啓動,新一輪問題正在問。 在這種情況下,有多個問題,所以當用戶回答第一個問題時,我希望它立即提出第二個問題。 問題是我有這樣的:

// Otherwise, ask our next question 
} else 
    context.Wait(AskQuestion); 

的getAnswer方法,它會等待繼續之前用戶的響應。我不希望它等待用戶響應,我希望它只是執行。有誰知道這是怎麼做到的嗎?

+0

既然你不使用IAwaitable 結果在您的AskQuestion方法......是什麼阻止你到方法中的邏輯提取到一個新的,不要沒有IAwaitable依賴關係,只需在else子句中調用該新方法? –

+0

是的,你是對的。我剛剛做到了。這就像當我開始使用機器人時,我的腦海裏停止了對正常邏輯的思考...... – r3plica

+0

好;不會將其作爲答案發布;只是看到你做到了。 –

回答

1

我正在啞巴。我只是改變了最後一行是:

// Otherwise, ask our next question 
} else 
    await AskQuestion(context, null);