Kami memiliki metode ini:
async Task<int> AccessTheWebAsync()
{
HttpClient client = new HttpClient();
Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");
// You can do work here that doesn't rely on the string from GetStringAsync.
DoIndependentWork();
string urlContents = await getStringTask;
//The thing is that this returns an int to a method that has a return type of Task<int>
return urlContents.Length;
}
Apakah konversi implisit terjadi antara Task<int>
dan int
? Jika tidak, lalu apa yang terjadi? Bagaimana penerapannya untuk bekerja?
async
kata kunci.Jawaban:
Nggak. Ini hanyalah bagian dari cara
async
/await
bekerja.Metode apa pun yang dideklarasikan
async
harus memiliki tipe kembalian:void
(hindari jika memungkinkan)Task
(tidak ada hasil selain pemberitahuan penyelesaian / kegagalan)Task<T>
(untuk hasil logis dari tipeT
dengan cara async)Kompilator melakukan semua pembungkusan yang sesuai. Intinya adalah Anda kembali secara asinkron
urlContents.Length
- Anda tidak dapat membuat metode hanya kembaliint
, karena metode sebenarnya akan kembali ketika mencapaiawait
ekspresi pertama yang belum selesai. Jadi, ia mengembalikan nilaiTask<int>
yang akan selesai ketika metode asinkron itu sendiri selesai.Perhatikan bahwa
await
tidak sebaliknya - itu unwraps sebuahTask<T>
keT
nilai, yang adalah bagaimana baris ini bekerja:... tapi tentu saja itu membuka bungkusnya secara tidak sinkron, sedangkan hanya menggunakan
Result
akan memblokir sampai tugas selesai. (await
dapat membuka jenis lain yang menerapkan pola yang dapat menunggu, tetapi yangTask<T>
paling sering Anda gunakan.)Pembungkusan / pembungkusan ganda inilah yang memungkinkan asinkron menjadi begitu mudah disusun. Misalnya, saya bisa menulis metode asinkron lain yang memanggil Anda dan menggandakan hasilnya:
(Atau
return await AccessTheWebAsync() * 2;
tentu saja.)sumber
async
/await
dan menurut saya ini sangat tidak intuitif. IMO, harus ada kata kunci atau serupa direturn
untuk membuatnya jelas, misalnyareturn async result;
(dengan cara yang sama yangawait result
"membuka"T
dariTast<T>
).await
- denganT foo = someTaskT;
Anda akan mendapatkan "Tidak bisa secara implisit mengubah tipeTask<T>
menjadiT
" - dengan cara yang sama saya berpendapat bahwa akan lebih masuk akal untuk memiliki kata kunci untuk invers (membungkus dalamTask<T>
). Saya semua untuk menghilangkan bulu tetapi dalam kasus ini saya pikir itu memberikan kebingungan yang tidak perlu dalamasync
metode. (Jelas intinya diperdebatkan karena kekuatan yang telah diucapkan / dikodekan!)async
, saya rasa itu sudah cukup.Tidak perlu mengubah Tugas menjadi int. Cukup Gunakan Hasil Tugas.
Ini akan mengembalikan nilai jika tersedia jika tidak mengembalikan 0.
sumber
Result
; itu bisa menyebabkan kebuntuan! Pertimbangkan misalnya alur kerja ini: (1) Tulis catatan yang mengatakan "potong rumput". (2) Menunggu rumput dipangkas (3) Makan sandwich, (4) Lakukan apa pun yang tertulis di catatan ". Dengan alur kerja itu, Anda tidak pernah makan sandwich atau memotong rumput, karena langkah 2 adalah menunggu yang sinkron tentang sesuatu yang akan Anda lakukan di masa depan . Tapi itulah alur kerja yang Anda gambarkan di sini.