Où puis-je marquer une expression lambda comme asynchrone?

215

J'ai ce code:

private async void ContextMenuForGroupRightTapped(object sender, RightTappedRoutedEventArgs args)
{
    CheckBox ckbx = null;
    if (sender is CheckBox)
    {
        ckbx = sender as CheckBox;
    }
    if (null == ckbx)
    {
        return;
    }
    string groupName = ckbx.Content.ToString();

    var contextMenu = new PopupMenu();

    // Add a command to edit the current Group
    contextMenu.Commands.Add(new UICommand("Edit this Group", (contextMenuCmd) =>
    {
        Frame.Navigate(typeof(LocationGroupCreator), groupName);
    }));

    // Add a command to delete the current Group
    contextMenu.Commands.Add(new UICommand("Delete this Group", (contextMenuCmd) =>
    {
        SQLiteUtils slu = new SQLiteUtils();
        slu.DeleteGroupAsync(groupName); // this line raises Resharper's hackles, but appending await raises err msg. Where should the "async" be?
    }));

    // Show the context menu at the position the image was right-clicked
    await contextMenu.ShowAsync(args.GetPosition(this));
}

... dont l'inspection de Resharper se plaignait, " Parce que cet appel n'est pas attendu, l'exécution de la méthode actuelle se poursuit avant la fin de l'appel. Envisagez d'appliquer l'opérateur 'wait' au résultat de l'appel " (sur la ligne avec le commentaire).

Et donc, je lui ai ajouté un "attente" mais, bien sûr, j'ai alors besoin d'ajouter un "async" quelque part aussi - mais où?

Clay Shannon
la source
1
@samsara: Nice, je me demande quand ils ont finalement documenté cela quelque part en dehors de la spécification C #. IIRC, aucune documentation n'existait au moment où cette question a été posée.
BoltClock

Réponses:

365

Pour marquer une async lambda, ajoutez simplement asyncavant sa liste d'arguments:

// Add a command to delete the current Group
contextMenu.Commands.Add(new UICommand("Delete this Group", async (contextMenuCmd) =>
{
    SQLiteUtils slu = new SQLiteUtils();
    await slu.DeleteGroupAsync(groupName);
}));
BoltClock
la source
Je reçois une erreur de Visual Studio indiquant que les méthodes void Async ne sont pas prises en charge.
Kevin Burton
@Kevin Burton: Oui, les vides asynchrones ne sont généralement limités qu'aux gestionnaires d'événements. L'API que vous utilisez n'est pas asynchrone ou possède une version asynchrone qui attend un lambda de tâche asynchrone à la place.
BoltClock
22

Et pour ceux d'entre vous qui utilisent une expression anonyme:

await Task.Run(async () =>
{
   SQLLiteUtils slu = new SQLiteUtils();
   await slu.DeleteGroupAsync(groupname);
});
Su Llewellyn
la source