microsoft / botframework-sdk

Bot Framework provides the most comprehensive experience for building conversation applications.
MIT License
7.5k stars 2.44k forks source link

ResumeDialogAsync of Parent not firing #6472

Open giobb opened 2 years ago

giobb commented 2 years ago

Version

4.15.2

Hi everyone. I have the same experience as the 3 stack overflow posters below. The EndDialogAsync documentation clearly states that the ResumeDialogAsync of the parent will fire after the child calls the EndDialogAsync. As one of the posters below asked, are we really missing something here?

https://stackoverflow.com/questions/55190353/bot-framework-resumedialogasync-not-firing https://stackoverflow.com/questions/58236708/resumedialogasync-on-microsoft-botframework-doesnt-fire https://stackoverflow.com/questions/59650364/when-calling-enddialogasync-on-child-dialog-resumedialogasync-doesnt-get-calle

breenbob commented 6 months ago

I'm also having this issue. Still persists in the latest 4.22.3 released 7 days ago.

Any plans to address the issue? Any suggestions for workarounds for this?

breenbob commented 6 months ago

Also, something weird in the documentation here:

The parent dialog is the dialog the started the on being ended via a call to either BeginDialogAsync(String, Object, CancellationToken) or PromptAsync(String, PromptOptions, CancellationToken).

breenbob commented 6 months ago

OK, think I have figured out the cause of the problem, for me at least.

My circumstance was a WaterfallDialog being shown inside a ComponentDialog, used to add other dialog types such as TextPrompt, AttachmentPrompt etc.

I luckily had verbose logging enabled, and noticed the Bot framework was logging the flow it was following to the output window. When I tried to end my child waterfall dialog, I was seeing log output like the below:

'message' ==> EndDialog ==> TextPrompt 'message' ==> ResumeDialog ==> ChildWaterfallDialog 'message' ==> EndDialog ==> ChildWaterfallDialog
'message' ==> EndDialog ==> ChildComponentDialog 'message' ==> ResumeDialog ==> TextPrompt

I would have expected ResumeDialog to be called on my Parent Waterfall Dialog. But it shows a TextPrompt instead. I quickly realised this is because I send 2 text prompts back in the active step of the parent dialog before beginning the child dialog.

I tried inspecting the Stack on the parent dialog before I begin the child dialog, and sure enough, the two TextPrompts are the last items in the stack, after my Parent waterfall dialog.

First I tried manipulating the stack:

  1. with stepContext.Stack.Clear() - that removed my parent waterfall too which ended all dialogs when the child completed.
  2. in a for loop in reverse order, to pop only items where the Id doesn't match my parent waterfall dialog - this didn't seem to be properly persisted after a postback, which was weird.
  3. I tried calling EndDialogAsync in the for loop instead, thinking this will properly dispose of my 2 text prompts. This caused a turn error.

Finally I realised that to keep it clean, those text prompts really belong inside the first step of the child waterfall dialog. When I moved them inside it instead, I ended up with the same flow (as far as the end user is concerned), but when EndDialogAsync is called in the child waterfall dialog, it finally called the next step of my parent waterfall model with the child waterfall dialog result passed in as stepContext.Result (without the need to override ResumeDialogAsync, as the documentation suggests).

Debatable whether this is incorrect behaviour, or incorrect/poor documentation. One would expect the parent dialog to be the dialog that called BeginDialogAsync to create the child. Documentation doesn't say anything to the contrary. Either way, given this issue posted 2+ years ago, I have concerns about this product.