web-dev-qa-db-fra.com

Syntaxe de Dispatcher BeginInvoke

J'ai essayé de suivre quelques exemples WCF Data Services et j'ai le code suivant:

private void OnSaveCompleted(IAsyncResult result)
    {
        Dispatcher.BeginInvoke(() =>
        {
            context.EndSaveChanges(result);
        });
    }

Qui s'appelle par ce qui suit:

this.context.BeginSaveChanges(SaveChangesOptions.Batch, this.OnSaveCompleted, null);

Maintenant, je suis un peu confus ici. Premièrement, le premier bit de code affiche une erreur de syntaxe de "l'expression lambda de type argument n'est pas attribuable au type de paramètre System.Delegate". Donc, au lieu d'essayer aveuglément de suivre l'exemple de code, j'ai essayé de comprendre ce qui se passait ici. Malheureusement, j'ai du mal à comprendre l'erreur et ce qui se passe réellement.

Je me sens un peu stupide car je suis sûr que c'est facile.

Merci d'avance pour toute illumination!

43
Jon Archway

Le problème est que le compilateur ne sait pas à quel type de délégué vous essayez de convertir l'expression lambda. Vous pouvez résoudre ce problème soit avec un cast, soit avec une variable distincte:

private void OnSaveCompleted(IAsyncResult result)
{        
    Dispatcher.BeginInvoke((Action) (() =>
    {
        context.EndSaveChanges(result);
    }));
}

ou

private void OnSaveCompleted(IAsyncResult result)
{
    Action action = () =>
    {
        context.EndSaveChanges(result);
    };
    Dispatcher.BeginInvoke(action);
}
95
Jon Skeet

La réponse de Jon Skeet est très bonne mais il existe d'autres possibilités. Je préfère "commencer à invoquer une nouvelle action" qui est facile à lire et à retenir pour moi.

private void OnSaveCompleted(IAsyncResult result)
{       
    Dispatcher.BeginInvoke(new Action(() =>
    {
        context.EndSaveChanges(result);
    }));
}

ou

private void OnSaveCompleted(IAsyncResult result)
{       
    Dispatcher.BeginInvoke(new Action(delegate
    {
        context.EndSaveChanges(result);
    }));
}

ou

private void OnSaveCompleted(IAsyncResult result)
{       
    Dispatcher.BeginInvoke(new Action(() => context.EndSaveChanges(result)));
}
11
CoperNick

Si votre méthode ne nécessite pas de paramètres, c'est la version la plus courte que j'ai trouvée:

Application.Current.Dispatcher.BeginInvoke((Action)MethodName); 
3
Alon Amsalem