async menunggu kembali Tugas


131

Adakah yang bisa menjelaskan apa artinya ini menjadi metode sinkron? Jika saya mencoba mengubah metode untuk asynckemudian VS mengeluh tentang hal itu.

Ini bekerja:

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

Ini tidak berfungsi:

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

Jadi pada dasarnya saya ingin tahu apa artinya ini: Task.FromResult<object>(null);



@ LB hmm berhasil! Tetapi juga jika saya hanya return;bekerja juga ...!
David Dury

2
"tidak berfungsi" tidak memberikan deskripsi yang sangat baik tentang apa yang tidak berfungsi. Apa pesan kesalahan yang Anda terima?
John Koerner

@ JohnKoerner Saya pikir cukup jelas bahwa kompiler mungkin memberi Anda kesalahan yang sama seperti jika Anda mencoba mengembalikan nilai dalam suatu voidfungsi.
binki

Jawaban:


236

asyncmetode berbeda dari metode normal. Apa pun yang Anda kembali dari asyncmetode terbungkus a Task.

Jika Anda mengembalikan tidak ada nilai (batal) itu akan dibungkus Task, Jika Anda mengembalikannya intakan dibungkus Task<int>dan sebagainya.

Jika metode async Anda perlu kembali, intAnda akan menandai jenis pengembalian metode sebagai Task<int>dan Anda akan kembali polos intbukan Task<int>. Compiler akan mengonversikan intke Task<int>untuk Anda.

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

Sameway, Ketika Anda kembali Task<object>, tipe pengembalian metode Anda seharusnyaTask<Task<object>>

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

Karena metode Anda kembali Task, seharusnya tidak mengembalikan nilai apa pun. Kalau tidak, itu tidak akan dikompilasi.

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

Perlu diingat bahwa metode async tanpa awaitpernyataan tidak async.


1
Bagi saya jenis pengembalian ini tidak berfungsi (saya kira saya melakukan sesuatu yang salah). Contoh Tugas async statis <string> DoStuff () {... = await SomeMethodAsync (); mengembalikan "nilai string"; } .. var x = DoStuff (); Tapi ini x - adalah dengan tipe "Task <string>", bukan dengan tipe "string" ... Kenapa begitu?
Prokurors

3
@Prokurors Anda harus menunggu DoStuff()juga. Misalnya:var x = await DoStuff();
Sriram Sakthivel

5
Seharusnyareturn await Task.FromResult<object>(null);
sandeep talabathula

@sandeeptalabathula itu sama dengan mengembalikan null
Sriram Sakthivel

2
@ProfK Task.WhenAnyadalah contohnya.
Servy

55

Anda harus menggunakan kata kunci tunggu ketika menggunakan async dan tipe pengembalian fungsi Anda harus umum Berikut adalah contoh dengan nilai balik:

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

Ini adalah contoh tanpa nilai balik:

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

Baca ini:

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

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


9
Anda bisa nulllangsung kembali daripada menunggu tugas dummy.
Lee

5
@ Lee, tetapi jika Anda melakukannya, kompiler mengeluh (memberikan peringatan) bahwa asyncmetode ini akan dijalankan secara tidak sinkron dengan saran untuk menggunakan awaitkata kunci di suatu tempat dalam metode. Saya sarankan hanya menggunakan return Task.FromResult((object)null);dan menghapus asynckata kunci untuk mengurangi kebisingan peringatan kompiler.
binki

Ya, saya telah mencoba hanya menggunakan returndalam Tugas, tetapi tugas terus dieksekusi, karena returntidak mengembalikan aTask
Turner Bass

30

Menambahkan kata kunci async hanyalah gula sintaksis untuk menyederhanakan pembuatan mesin negara. Intinya, kompiler mengambil kode Anda;

public async Task MethodName()
{
     return null;
}

Dan mengubahnya menjadi;

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

Jika kode Anda memiliki awaitkata kunci, kompiler harus mengambil metode Anda dan mengubahnya menjadi kelas untuk mewakili mesin negara yang diperlukan untuk menjalankannya. Di setiap awaitkata kunci, keadaan variabel dan tumpukan akan dipertahankan di bidang kelas, kelas akan menambahkan dirinya sebagai kait penyelesaian untuk tugas yang Anda tunggu, lalu kembali.

Ketika tugas itu selesai, tugas Anda akan dieksekusi lagi. Jadi beberapa kode tambahan ditambahkan ke bagian atas metode untuk mengembalikan keadaan variabel dan melompat ke lempengan kode Anda berikutnya.

Lihat Apa yang dihasilkan async & tunggu? untuk contoh berdarah.

Proses ini memiliki banyak kesamaan dengan cara kompiler menangani metode iterator dengan pernyataan hasil.


2

Ini adalah Tugas yang mengembalikan Tugas tipe String (C # fungsi anonim atau dengan kata lain delegasi digunakan '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
Saat memposting kode sebagai jawaban, harap sertakan beberapa penjelasan tentang apa yang Anda tunjukkan. Dalam hal ini, Anda menambahkan jawaban ke pertanyaan lama yang sudah memiliki beberapa jawaban. Harap tambahkan satu atau dua kalimat yang menggambarkan apa yang ditunjukkan oleh jawaban baru Anda, yang belum ditampilkan di jawaban lainnya. Saya tidak mengatakan ada yang salah dengan jawaban Anda, hanya meminta Anda membantu orang lain dengan menuliskan kata-kata apa yang Anda tunjukkan dengan kode Anda.
ToolmakerSteve

0

Untuk mendapatkan respons yang tepat kembali dari metode async, Anda harus menunggu sementara memanggil metode tugas tersebut. Itu akan menunggu untuk mengubahnya kembali ke tipe nilai yang dikembalikan dan bukan tipe tugas.

Misalnya konten var = menunggu StringAsyncTask (

di mana publik async Task < String > StringAsyncTask ())

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.