async attente de retour de la tâche

131

Quelqu'un peut-il expliquer ce que cela signifie dans une méthode synchrone? Si j'essaie de changer la méthode, asyncalors VS m'en plaint.

Cela marche:

public Task MethodName()
{
     return Task.FromResult<object>(null);
}

Cela ne fonctionne pas:

public async Task MethodName()
{
     return Task.FromResult<object>(null);
}

Donc, fondamentalement, j'aimerais savoir ce que cela signifie exactement: Task.FromResult<object>(null);

David Dury
la source
1
Lisez également MSDN: msdn.microsoft.com/en-us/library/hh194922(v=vs.110).aspx .
Patrick Hofman
@LB hmm ça marche! Mais aussi si je return;travaille aussi ...!
David Dury
2
«ne fonctionne pas» ne fournit pas une très bonne description de ce qui ne fonctionne pas. Quel est le message d'erreur que vous recevez?
John Koerner
@JohnKoerner Je pense qu'il est assez évident que le compilateur peut vous donner la même erreur que si vous tentiez de renvoyer une valeur dans une voidfonction.
binki

Réponses:

236

asyncles méthodes sont différentes des méthodes normales. Tout ce que vous retournez des asyncméthodes est enveloppé dans un fichier Task.

Si vous ne retournez aucune valeur (nulle), elle sera enveloppée Task, si vous retournez, intelle sera enveloppée Task<int>et ainsi de suite.

Si votre méthode asynchrone doit retourner, intvous marquez le type de retour de la méthode comme Task<int>et vous retournerez plain intpas le Task<int>. Le compilateur convertira le inten Task<int>pour vous.

private async Task<int> MethodName()
{
    await SomethingAsync();
    return 42;//Note we return int not Task<int> and that compiles
}

De même, lorsque vous retournez Task<object>le type de retour de votre méthode doit êtreTask<Task<object>>

public async Task<Task<object>> MethodName()
{
     return Task.FromResult<object>(null);//This will compile
}

Puisque votre méthode est de retour Task, elle ne doit renvoyer aucune valeur. Sinon, il ne se compilera pas.

public async Task MethodName()
{
     return;//This should work but return is redundant and also method is useless.
}

Gardez à l'esprit que la méthode async sans awaitinstruction ne l'est pas async.

Sriram Sakthivel
la source
1
Pour moi, ce type de retour ne fonctionne pas (je suppose que je fais quelque chose de mal). Exemple de tâche asynchrone statique <string> DoStuff () {... = await SomeMethodAsync (); retourne "valeur de chaîne"; } .. var x = DoStuff (); Mais ce x - est de type "Task <string>", pas de type "string" ... Pourquoi est-ce ainsi?
Prokurors
3
@Prokurors Vous devez DoStuff()également attendre . Par exemple:var x = await DoStuff();
Sriram Sakthivel
5
Devrait êtrereturn await Task.FromResult<object>(null);
sandeep talabathula
@sandeeptalabathula qui est égal à return null
Sriram Sakthivel
2
@ProfK en Task.WhenAnyest un exemple.
Servy
55

Vous devez utiliser le mot clé await lorsque vous utilisez async et votre type de retour de fonction doit être générique Voici un exemple avec valeur de retour:

public async Task<object> MethodName()
{
    return await Task.FromResult<object>(null);
}

Voici un exemple sans valeur de retour:

public async Task MethodName()
{
    await Task.CompletedTask;
}

Lisez ces:

TPL: http://msdn.microsoft.com/en-us/library/dd460717(v=vs.110).aspx et tâches: http://msdn.microsoft.com/en-us/library/system.threading .tasks (v = contre 110) .aspx

Async: http://msdn.microsoft.com/en-us/library/hh156513.aspx Attendre: http://msdn.microsoft.com/en-us/library/hh156528.aspx

Majeur
la source
9
Vous pouvez simplement revenir nulldirectement au lieu d'attendre une tâche factice.
Lee
5
@Lee, mais si vous faites cela, le compilateur se plaint (donne un avertissement) que la asyncméthode s'exécutera de manière asynchrone avec une suggestion d'utiliser le awaitmot - clé quelque part dans la méthode. Je suggère simplement d'utiliser return Task.FromResult((object)null);et de supprimer le asyncmot - clé pour réduire le bruit d'avertissement du compilateur.
binki
Oui, j'ai essayé d'utiliser uniquement returndans une tâche, mais la tâche continue de s'exécuter, car elle returnne renvoie pas unTask
Turner Bass
30

L'ajout du mot-clé async n'est que du sucre syntaxique pour simplifier la création d'une machine à états. En substance, le compilateur prend votre code;

public async Task MethodName()
{
     return null;
}

Et le transforme en;

public Task MethodName()
{
     return Task.FromResult<object>(null);
}

Si votre code a des awaitmots-clés, le compilateur doit prendre votre méthode et la transformer en une classe pour représenter la machine à états requise pour l'exécuter. A chaque awaitmot-clé, l'état des variables et de la pile seront conservés dans les champs de la classe, la classe s'ajoutera comme hook de complétion à la tâche que vous attendez, puis reviendra.

Une fois cette tâche terminée, votre tâche sera à nouveau exécutée. Ainsi, du code supplémentaire est ajouté en haut de la méthode pour restaurer l'état des variables et passer à la dalle suivante de votre code.

Voir Que génère async & await? pour un exemple sanglant.

Ce processus a beaucoup en commun avec la façon dont le compilateur gère les méthodes d'itération avec des instructions yield.

Jeremy Lakeman
la source
2

Il s'agit d'une tâche qui renvoie une tâche de type String (fonction anonyme C # ou en d'autres termes une délégation est utilisée 'Func')

    public static async Task<string> MyTask()
    {
        //C# anonymous AsyncTask
        return await Task.FromResult<string>(((Func<string>)(() =>
        {
            // your code here
            return  "string result here";

        }))());
    }
Adel Mourad
la source
1
Lorsque vous publiez un code comme réponse, veuillez inclure une explication de ce que vous démontrez. Dans ce cas, vous ajoutez une réponse à une ancienne question qui a déjà plusieurs réponses. Veuillez ajouter une phrase ou deux décrivant ce que démontre votre nouvelle réponse, qui ne figurait pas déjà dans les autres réponses. Je ne dis pas que votre réponse ne va pas, je vous demande simplement d'aider les autres en mettant des mots sur ce que vous montrez avec votre code.
ToolmakerSteve
0

Afin de récupérer les réponses appropriées des méthodes asynchrones, vous devez mettre en attente lors de l'appel de ces méthodes de tâche. Cela attendra de le reconvertir dans le type de valeur retourné plutôt que dans le type de tâche.

Par exemple, var content = wait StringAsyncTask (

où public async Task < String > StringAsyncTask ())

abhiroop mukherjee
la source