72

I've got a c# Windows Store app. I'm trying to launch a MessageDialog when one of the command buttons inside another MessageDialog is clicked. The point of this is to warn the user that their content is unsaved, and if they click cancel, it will prompt them to save using a separate save dialog.

Here's my "showCloseDialog" function:

private async Task showCloseDialog()
{
  if (b_editedSinceSave)
  {
    var messageDialog = new MessageDialog("Unsaved work! Close anyway?"
                                            , "Confirmation Message");

    messageDialog.Commands.Add(new UICommand("Yes", (command) =>
    {
      // close document
      editor.Document.SetText(TextSetOptions.None, "");
    }));

    messageDialog.Commands.Add(new UICommand("No", (command) =>
    {
      // save document
      await showSaveDialog();
    }));

    messageDialog.DefaultCommandIndex = 1;
    await messageDialog.ShowAsync();
  }
}

In VS I get a compiler error:

The 'await' operator can only be used within an async lambda expression. Consider marking this lambda expression with the 'async' modifier`

The method is marked with await. If I remove await from before showSaveDialog, it compiles (and works) but I get a warning that I really should use await

How do I use await in this context?

surfmuggle
  • 5,527
  • 7
  • 48
  • 77
roryok
  • 9,325
  • 17
  • 71
  • 138
  • 3
    The lambda delegate is not marked as async `(command) =>` – Silvermind Dec 15 '13 at 10:31
  • 1
    As a side note, if I get a program that asks me "Unsaved work detected. Close anyway?", and click "No", I expect the operation to be cancelled. I don't expect the program to save the file, or offer to save the file. For the behaviour you're after, the question "Unsaved work detected. Save before closing?" might be more appropriate. –  Dec 15 '13 at 10:43
  • @hvd this is only placeholder text at the moment, but I appreciate the suggestion! – roryok Dec 15 '13 at 15:47

2 Answers2

134

You must mark your lambda expression as async, like so:

messageDialog.Commands.Add(new UICommand("No", async (command) =>
{
    await showSaveDialog();
}));
p.campbell
  • 98,673
  • 67
  • 256
  • 322
Boris Parfenenkov
  • 3,219
  • 1
  • 25
  • 30
1

In my case I needed to call an asynchronous method inside a async foreach. The solution was something like this:

await list.ForEachAsync(async item =>
{
    IEnumerable<Object> data = await _repository.Get();
});
Dharman
  • 30,962
  • 25
  • 85
  • 135