async attende il ritorno Task


131

Qualcuno può spiegare cosa significa questo in un metodo sincrono? Se provo a cambiare il metodo per asyncpoi VS mi lamento.

Questo funziona:

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

Questo non funziona:

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

Quindi sostanzialmente vorrei sapere cosa significa esattamente questo: Task.FromResult<object>(null);



@LB hmm che funziona! Ma anche se return;lavoro anche ...
David Dury,

2
"non funziona" non fornisce un'ottima descrizione di ciò che non funziona. Qual è il messaggio di errore che ricevi?
John Koerner,

@JohnKoerner Penso che sia abbastanza ovvio che il compilatore potrebbe dare lo stesso errore come se si provasse a restituire un valore in una voidfunzione.
binki,

Risposte:


236

asynci metodi sono diversi dai metodi normali. Qualunque cosa tu ritorni dai asyncmetodi è racchiusa in a Task.

Se non si restituisce alcun valore (vuoto) verrà inserito Task, Se si restituisce intverrà inserito Task<int>e così via.

Se il tuo metodo asincrono deve essere restituito int, contrassegnerai il tipo restituito del metodo come Task<int>e restituirai semplicemente intnon il Task<int>. Compilatore converte il intper Task<int>per voi.

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

Allo stesso modo, quando Task<object>ritorni dovrebbe essere il tipo di ritorno del tuo metodoTask<Task<object>>

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

Poiché il tuo metodo sta tornando Task, non dovrebbe restituire alcun valore. Altrimenti non verrà compilato.

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

Tieni presente che il metodo asincrono senza awaitun'istruzione non lo è async.


1
Per me questo tipo di ritorno non funziona (immagino che sto facendo qualcosa di sbagliato). Esempio di attività asincrona statica <string> DoStuff () {... = await SomeMethodAsync (); restituisce "valore stringa"; } .. var x = DoStuff (); Ma questo x - è con il tipo "Task <stringa>", non con il tipo "stringa" ... Perché è così?
Prokurors,

3
@Prokurors Devi aspettare DoStuff()anche tu . Ad esempio:var x = await DoStuff();
Sriram Sakthivel,

5
Dovrebbe esserereturn await Task.FromResult<object>(null);
sandeep talabathula,

@sandeeptalabathula che equivale a restituire null
Sriram Sakthivel

2
@ProfK Task.WhenAnyè un esempio.
Servito il

55

Devi usare la parola chiave wait quando usi asincrono e il tuo tipo di ritorno di funzione dovrebbe essere generico Ecco un esempio con valore di ritorno:

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

Ecco un esempio senza valore di ritorno:

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

Leggi questo:

TPL: http://msdn.microsoft.com/en-us/library/dd460717(v=vs.110).aspx e attività: http://msdn.microsoft.com/en-us/library/system.threading .tasks (v = vs.110) .aspx

Asincrono: http://msdn.microsoft.com/en-us/library/hh156513.aspx In attesa: http://msdn.microsoft.com/en-us/library/hh156528.aspx


9
Puoi semplicemente tornare nulldirettamente invece di attendere un'attività fittizia.
Lee,

5
@Vedi, ma se lo fai, il compilatore si lamenta (dà un avvertimento) che il asyncmetodo verrà eseguito in modo asincrono con un suggerimento per usare la awaitparola chiave da qualche parte nel metodo. Suggerisco solo di utilizzare return Task.FromResult((object)null);e rimuovere la asyncparola chiave per ridurre il rumore di avviso del compilatore.
binki,

Sì, ho provato a utilizzare solo returnin un'attività, ma l'attività continua a essere eseguita, perché returnnon restituisce unTask
Turner Bass

30

L'aggiunta della parola chiave asincrona è solo zucchero sintattico per semplificare la creazione di una macchina a stati. In sostanza, il compilatore prende il tuo codice;

public async Task MethodName()
{
     return null;
}

E lo trasforma in;

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

Se il tuo codice ha delle awaitparole chiave, il compilatore deve prendere il tuo metodo e trasformarlo in una classe per rappresentare la macchina a stati richiesta per eseguirlo. Ad ogni awaitparola chiave, lo stato delle variabili e lo stack verranno conservati nei campi della classe, la classe si aggiungerà come hook di completamento all'attività in attesa, quindi ritornerà.

Al termine dell'attività, l'attività verrà eseguita di nuovo. Quindi un po 'di codice extra viene aggiunto all'inizio del metodo per ripristinare lo stato delle variabili e passare al pannello successivo del codice.

Vedi cosa genera asincrono e attendi? per un esempio cruento.

Questo processo ha molto in comune con il modo in cui il compilatore gestisce i metodi iteratore con dichiarazioni di rendimento.


2

Questa è un'attività che restituisce un'attività di tipo String (funzione anonima C # o in altre parole una delega viene utilizzata 'Func')

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

        }))());
    }

1
Quando si inserisce il codice come risposta, si prega di includere alcune spiegazioni di ciò che si sta dimostrando. In questo caso, stai aggiungendo una risposta a una vecchia domanda che ha già diverse risposte. Aggiungi una o due frasi che descrivono ciò che sta dimostrando la tua nuova risposta, che non era già mostrato nelle altre risposte. Non sto dicendo che c'è qualcosa di sbagliato nella tua risposta, sto solo chiedendo di aiutare gli altri mettendo in parole ciò che stai mostrando con il tuo codice.
ToolmakerSteve

0

Per ottenere risposte adeguate dai metodi asincroni, è necessario attendere mentre si chiamano quei metodi di attività. Ciò attenderà la conversione al tipo di valore restituito anziché al tipo di attività.

Ad esempio var content = await StringAsyncTask (

dove Attività pubblica asincrona < String > StringAsyncTask ())

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.