Saya ingin membuat yang selesai Task
(tidak Task<T>
). Apakah ada sesuatu yang dibangun dalam. NET untuk melakukan ini?
Pertanyaan terkait: Buat Tugas selesai <T>
c#
.net
async-await
task-parallel-library
Perisai Timothy
sumber
sumber
It seems like the answer I'm getting from everyone is that using a garbage value like this is the correct way. That there isn't a way to do this without the garbage value is disappointing -- oh well.
Menurut Anda masalah apa yang terjadi? Jika Anda men-cache satuTask
maka seluruh program Anda memakan satu bit ekstra memori. Bukan apa - apa . Juga, seseorang dapat membuat tugas yang selesai tanpa melakukan itu, itu tidak akan lebih baik.ValueTask
untuk tugas yang diselesaikan (yaitu untuk nilai yang sudah Anda miliki sehingga kode pada dasarnya sinkron), yang akan menghemat alokasi.Jawaban:
Versi terbaru .Net (v4.6) menambahkan hanya itu, Task.CompletedTask bawaan :
Properti itu diimplementasikan sebagai singleton tanpa kunci sehingga Anda hampir selalu menggunakan tugas yang sama.
sumber
Task.CompletedTask
masih internal.Task<T>
secara implisit dapat dikonversiTask
, jadi dapatkan yang lengkapTask<T>
(denganT
nilai apa saja dan apa saja) dan gunakan itu. Anda dapat menggunakan sesuatu seperti ini untuk menyembunyikan fakta bahwa hasil aktual ada di sana, di suatu tempat.Perhatikan bahwa karena kami tidak mengekspos hasilnya, dan tugas selalu selesai, kami dapat men-cache satu tugas dan menggunakannya kembali.
Jika Anda menggunakan .NET 4.0 dan tidak memilikinya,
FromResult
Anda dapat membuatnya sendiri menggunakanTaskCompletionSource
:sumber
Metode pilihan saya untuk melakukan ini adalah menelepon
Task.WhenAll()
tanpa argumen. The MSDN dokumentasi menyatakan bahwa "Jika disediakan array / enumerable tidak mengandung tugas, tugas kembali akan segera transisi ke keadaan RanToCompletion sebelum itu kembali ke pemanggil.". Kedengarannya seperti yang Anda inginkan.Pembaruan: Saya menemukan sumbernya di Sumber Referensi Microsoft ; di sana Anda dapat melihat bahwa Tugas. Ketika Semua berisi yang berikut:
Jadi Task.CompletedTask memang internal, tetapi diekspos dengan memanggil WhenAll () tanpa argumen.
sumber
Saya akan menggunakan
Task.Delay(0)
. Secara internal, ia mengembalikan contoh cache yang selesaiTask<T>
. Ini persis seperti apa yang disarankan oleh jawaban saat ini, hanya sekarang Anda tidak perlu membuat cache contoh sendiri, juga tidak memiliki nilai sampah yang salah dalam kode Anda.Anda mungkin berpikir Anda dapat menggunakan
Task.Yield()
sebagai gantinya, tapi ternyata hasilTask.Yield()
ini bukan subtipe dariTask
, sedangkan hasilTask.Delay(0)
adalah. Itulah salah satu perbedaan halus antara keduanya.sumber
Anda dapat menggunakan Task.FromResult (dalam .NET 4.5) untuk mengembalikan yang sudah selesai
Task<T>
.Jika Anda memerlukan non-generik
Task
, Anda selalu dapat menggunakanTask.FromResult(0)
atau serupa, karenaTask<T>
merupakan subkelas dariTask
.sumber
Untuk .Net 4.6 dan penggunaan di atas
Untuk versi yang lebih rendah, Anda dapat menggunakan
sumber
return Task.Delay(0);
saja?Anda dapat menggunakan Nito.AsyncEx.TaskConstants.Completed dari perpustakaan besar AsyncEx dari Stephen Cleary .
sumber
Bagaimana tentang:
Anda dapat meninggalkan penindasan peringatan jika Anda tidak keberatan.
sumber
async
masih menciptakan peralatan mesin seluruh negara bahkan jika Anda tidak menggunakannya, jadi mengembalikan tugas kosong lebih efisien untuk skenario sumber daya rendah.