2016-11-12 3 views
0

J'ai la méthode suivanteComment réparer cette méthode .NET qui a un func comme argument?

public async Task<dynamic> FooAsync(dynamic parameters, 
            CancellationToken cancellationToken) 
{..} 

Mais je ne peux pas sembler trouver un moyen d'appeler à l'aide correctement cette méthode:

public async Task<dynamic> TryAsync(Func<dynamic, CancellationToken, Task<dynamic>> func) 
{ 
    try 
    { 
     await func(); // Doesn't compile. Says it missing the 2 arguments. 
    } 
    catch(Exception exception) 
    { 
     .. 
    } 
} 

par exemple code qui passe FooAsync-TryAsync ..

public async Task PewPewAsync(..) 
{ 
    ... 
    // TODO: Get this to work/compile :(
    var result = await TryAsync(FooAsync(parameters, cancellationToken); 
    ... 
} 

peut-elle aider quelqu'un s'il vous plaît?

+0

Trouvé [presque la même question] (http://stackoverflow.com/questions/40558237/why-does-this-async-lambda-function- invocation-non-compilation-en-c)! – ventiseis

Répondre

3

Vous avez un délégué qui prend deux paramètres (dynamic et CancellationToken) et vous essayez de l'invoquer avec zéro arguments.

Selon ce que vous voulez faire, vous pouvez faire TryAsync accepter les deux paramètres et puis les passer en l'appelant:

public async Task<dynamic> TryAsync(
    Func<dynamic, CancellationToken, Task<dynamic>> func, 
    dynamic parameters, CancellationToken cancellationToken) 
{ 
    try 
    { 
     return await func(parameters, cancellationToken); 
    } 
    catch(Exception exception) 
    { 
     .. 
    } 
} 

TryAsync(FooAsync, parameters, cancellationToken); 

Ou vous pouvez prendre un délégué qui ne dispose pas de paramètres et l'utilisation un lambda en l'appelant:

public async Task<dynamic> TryAsync(Func<Task<dynamic>> func) 
{ 
    try 
    { 
     return await func(); 
    } 
    catch(Exception exception) 
    { 
     .. 
    } 
} 

TryAsync(() => FooAsync(parameters, cancellationToken)); 
+0

Hmm .. Je reçois la ligne rouge-squiggly _under_ 'FooAsync' en essayant de faire cet appel ... ref: http://i.imgur.com/9FZWQha.png (NOTE: ignorer les appels d'erreur de recréation. fouetté cela pour obtenir une capture d'écran.) –

+0

Cela fonctionne très bien si le type de 'paramètres' n'est pas' dynamic'. Mais si vous voulez l'avoir 'dynamic', vous devrez ajouter un cast:' TryAsync ((Func >) FooAsync, paramètres, cancellationToken); '. – svick

0

Essayez cette

public async Task<dynamic> TryAsync(Func<dynamic, CancellationToken, Task<dynamic>> func, dynamic parameters, CancellationToken cancellationToken) 
{ 
    try 
    { 
     await func(parameters, cancellationToken); 
    } 
    catch(Exception exception) 
    { 
     .. 
    } 
} 

Et appeler comme ça

public async Task PewPewAsync(..) 
{ 
    ... 
    var result = await TryAsync(FooAsync, parameters, cancellationToken); 
    ... 
} 

La raison en est que vous devez passer les paramètres à la fonction que vous voulez appeler/envelopper séparément afin que vous puissiez les transmettre à l'invocation réelle. Dans votre code d'origine, vous appelez la fonction et transmettez la valeur de retour en tant que paramètre à TryAsync, sans passer une référence à la fonction elle-même.

+0

Hmm ... Je n'arrive pas à compiler la première ligne ?? ref: http://i.imgur.com/bR955Ih.png –

+0

Mon mauvais, j'ai manqué les déclarations de type de certains des paramètres de la fonction. J'ai mis à jour le code à nouveau. –

0

Cela dépend de ce que vous essayez de réaliser avec TryAsync. Une méthode est montrée dans une autre réponse. L'autre façon est

public async Task<dynamic> TryAsync(Func<Task<dynamic>> func) { 
    try { 
     var result = await func(); 
     return result; 
    } 
    catch (Exception exception) { 
     // do something 
     return null; 
    } 
} 

Appel comme celui-ci

var result = await TryAsync(() => FooAsync(parameters, cancellationToken)); 
+0

Ceci ne sera pas compilé. – svick

+0

@svick Eh bien, vous avez peut-être remarqué que le code original ne sera pas compilé ... Mais d'accord, ajouté "return null". – Evk

+1

Je voulais dire que 'TryAsync' prend un' Func > ', mais vous passez dans' Task '. – svick

0

cela dépend - quand que vous voulez exécuter FooAsync?

Dans TryAsync ou avant? Si vous voulez exécuter tout TryAsync, vous pouvez utiliser:

public async Task<dynamic> FooAsync(dynamic parameters, CancellationToken cancellationToken) { 
     return await Task.FromResult("x"); 
    } 

    public async Task<dynamic> TryAsync(Func<Task<dynamic>> func) { 
     try { 
      return await func(); // Doesn't compile. Says it missing the 2 arguments. 
     } 
     catch (Exception exception) { 
      return Task.FromResult(false); 
     } 
    } 

    public async Task PewPewAsync() { 
     var parameters = "x"; 
     var cancellationToken = CancellationToken.None; 
     var result = await TryAsync(() => FooAsync(parameters, cancellationToken)); 
    }