Reputation:
I have a bot with a "root" dialog that runs child dialogs using context.Call()
or context.Forward()
depending on the user's choice, like so:
context.Call(new QuestionsDialog(), ChildDialogComplete);
After the child dialog exits, the control is passed to this method, ChildDialogComplete
. It outputs a prompt and waits for the user's reply.
public async Task ChildDialogComplete(IDialogContext context, IAwaitable<object> argument)
{
var unnecessaryTemp = await argument;
var restartPrompt = context.MakeMessage();
restartPrompt.Text = "Say \"hi\" again if I can help with anything else!";
await context.PostAsync(restartPrompt);
context.Wait(MainScreenSelectionReceived);
}
When debugging, the last line of the method with context.Wait()
causes this exception in the emulator:
Exception: System.ArgumentNullException: Value cannot be null. Parameter name: wait at Microsoft.Bot.Builder.Internals.Fibers.Fiber1.-PollAsync>d__13.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at Microsoft.Bot.Builder.Internals.Fibers.Wait 2.Microsoft.Bot.Builder.Internals.Fibers.IAwaiter.GetResult() at Microsoft.Bot.Builder.Dialogs.Chain.LoopDialog1.d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
...and so on
This error doesn't occur when ChildDialogComplete
is run "naturally", when a dialog exits. It only occurs when I try to call this method manually, from another part of the root dialog, like so:
ChildDialogComplete(context, argument);
Where context
and argument
are the two standard parameters of methods in an IDialog (IDialogContext context, IAwaitable<IMessageActivity> argument
).
The argument
was previously await
ed before being passed to the method. But I assume this is not an issue because the exception occurs at the context.Wait()
line which seems unrelated to IAwaitable
.
Upvotes: 1
Views: 1586
Reputation: 14787
You cannot pass the awaited value to a method expecting an IAwaitable<T>
. Also, you are doing await twice into the argument if that's the case (one before calling the method, and another one inside the method)
Refactor your code to extract all the logic inside the ChildDialogComplete
method so you end up with two methods, one receiving the IAwaitable<T>
and the other one just the value. The one receiving the IAwaitable should await the argument and call the new method.
However, you are not using the argument in that method, so if that would be the case; you don't need to refactor and you could just call the ChildDialogComplete
with null
for the IAwaitable<T>
parameter after removing the await argument
call of your method
ChildDialogComplete(context, null);
Upvotes: 1