web-dev-qa-db-fra.com

Méthode de tâche C # Async sans attente ni retour

J'ai une interface I qui est implémentée à deux endroits comme:

interface I 
{ 
   Task DoSomething();
}

L'interface possède une API de méthode async Task DoSomething qui est ensuite implémentée en classe A comme:

class A : I {....}

class B : I {....}

Dans la classe A, l'implémentation de DoSomething est comme ci-dessous et c'est OK:

public async Task DoSomething()
{
    if (...)
    {
        await DoIt();
    }
}

Cependant, dans la classe B, l'implémentation de DoSomething () ne devrait rien faire. Donc, sa mise en œuvre ressemble à ceci:

public async Task DoSomething()
{
    // nothing
}

Cela compile mais je ne sais pas dans quelle mesure il est correct de faire quelque chose comme ça à côté du fait que la méthode est inutile.

Mais être "inutile" dans ce cas est correct dans ce cas car il est implémenté simplement parce qu'il est requis par la classe B implémentant l'interface I.

Je me demande si c'est une façon correcte d'implémenter une méthode qui renvoie une tâche asynchrone mais qui n'a pas d'attente ou de retour? Je sais que cette méthode ne fera rien et s'exécutera de manière synchrone car il n'y a aucun appel à attendre.

MISE À JOUR: Des questions similaires ont été posées ici sur SO et je les ai toutes vérifiées avant de poser celle-ci. Personne ne demande ce que je demande cependant

10
pixel
public Task DoSomething()
{
    return Task.CompletedTask;
}

Pas besoin de async.

Si vous utilisez une ancienne version de .NET, utilisez ceci:

public Task DoSomething()
{
    return Task.FromResult(0);
}

Si vous trouvez que vous devez retourner un résultat mais que vous n'avez toujours pas besoin de await quoi que ce soit, essayez;

public Task<Result> DoSomething()
{
    Task.FromResult(new Result())
}

ou, si vous voulez vraiment utiliser async (non recommandé);

public async Task<Result> DoSomething()
{
    return new Result();
}
28
sellotape

Je vois que la plupart des gens préfèrent laisser de côté le async et utiliser Task.ComletedTask À la place. Mais même si await n'est pas utilisé, il y a toujours une grande différence dans la gestion des exceptions

Considérez l'exemple suivant

static async Task Main(string[] args)
{

    Task task = test(); // Will throw exception here
    await task;

    Task taskAsync = testWithAsync();
    await taskAsync; // Will throw exception here
}

static Task test()
{
    throw new Exception();
    return Task.CompletedTask; //Unreachable, but left in for the example
}

static async Task testWithAsync()
{
    throw new Exception();
}

En utilisant

test().ContinueWith(...); ou Task.WhenAll(test())

peut entraîner un comportement inattendu.

Par conséquent, je préfère async au lieu de Task.CompletedTask Ou Task.FromResult.

0
Jan-Fokke