Artikel ini adalah artikel cermin dari terjemahan mesin, silakan klik di sini untuk melompat ke artikel aslinya.

Melihat: 15343|Jawab: 2

[Komunikasi] [Terjemahan]. NET untuk menggunakan perbedaan antara ValueTask dan Task

[Salin tautan]
Dipaparkan pada 2022-3-17 11:21:50 | | | |


Menggunakan kelas Tugas atau Tugas memiliki hambatan performa yang tidak kami sebutkan di artikel sebelumnya. Singkatnya, kelas-kelas ini memimpin ketika hasilnya segera tersediaAlokasi yang tidak perlu。 Ini berarti bahwa objek Tugas atau Tugas baru akan selalu dibuat meskipun hasilnya sudah tersedia. Sekarang, kami menyebutkan bahwa konsep async/await yang kami gunakan di artikel sebelumnya telah ada sejak rilis .NET 4.5. Fitur ini telah ditingkatkan sejak C# 7 dengan versi .NET 4.7 dengan struktur ValueTask yang dapat digunakan sebagai pengembalian untuk fungsi asinkron.

Struktur ValueTask


Struktur ValueTask pertama kali muncul di repositori corefxlab pada tahun 2015. Repositori ini digunakan untuk bereksperimen dan mengeksplorasi ide-ide baru yang mungkin atau mungkin tidak berhasil masuk ke repositori corefx utama. Repositori Corefx adalah repositori tempat semua pustaka dasar .NET Core berada. Ini dikembangkan dan disarankan oleh Stephen Taub untuk perpustakaan System.Threading.Tasks.Channels. Saat itu, Stephen memberikan penjelasan singkat:

Alamat perpustakaan Corefxlab:Login hyperlink terlihat.


ValueTask adalah penyatuan yang berbeda dari T dan Task, memungkinkan ReadAsync mengalokasikan secara bebas untuk mengembalikan nilai T yang tersedia secara sinkron (tidak seperti menggunakan Task.FromResult, yang memerlukan alokasi instance Task). ValueTask dapat dibayar, sehingga konsumsi sebagian besar instans tidak dapat dibedakan dari konsumsi tugas.
Banyak orang melihat manfaat menggunakan struktur ini, yang disertakan dalam C# 7 sebagai bagian dari paket NuGet System.Threading.Tasks.Extensions. Jadi, sebelum kita menyelami struktur ValueTask, mari kita periksa masalah yang digunakan untuk memecahkannya. Karena Task(Task) adalah jenis referensi, mulailah denganMetode asinkron yang mengembalikan objek Task berarti bahwa objek tersebut dialokasikan pada tumpukan setiap saat。 Ini diperlukan dalam banyak kasus.

Namun, dalam beberapa kasus, metode asinkron mengembalikan hasil segera atau selesai secara sinkron. Dalam kasus ini, alokasi ini tidak perlu dan dapat menjadi mahal di bagian kode yang penting dalam performa. Sampai rilis .NET 4.7, tidak ada cara untuk menghindari hal ini, karena metode asinkron harus mengembalikan Task, Task, <T>atau void (yang terakhir biasanya tidak diinginkan). Dalam versi .NET ini, ini diperluas, artinya metode asinkron dapat mengembalikan jenis apa pun selama memiliki metode GetAwaiter yang dapat diakses. ValueTask adalah contoh konkret dari jenis ini, dan juga ditambahkan ke rilis ini.

Anda dapat menelusuri repositori corefx dan melihat implementasi lengkap ValueTask, berikut adalah bagian API yang kami minati:



Sebagai struktur, ValueTask memungkinkan penulisan metode asinkron yang tidak mengalokasikan memori selama runtime sinkron. Konsistensi API dari konsep async/await tidak dikompromikan dengan cara ini. Selain itu, struktur ini menunggu dengan sendirinya, membuatnya mudah digunakan. Misalnya, jika kita menjalankan kode sederhana ini:

Dalam metode MultiplyAsync, kita mensimulasikan situasi di mana kita ingin menghindari penggunaan Task dan hanya mengembalikan bilangan bulat sederhana. Ini dilakukan dalam pernyataan if metode, di mana pada dasarnya kita memeriksa apakah parameter yang dilewati adalah nol. Masalahnya adalahBahkan jika kondisi kita dalam pernyataan if adalah true, kode di atas membuat objek Task。 Kami memecahkan masalah ini seperti ini:

NilaiTugas dan Tugas



Seperti disebutkan sebelumnya, ada dua manfaat utama menggunakan ValueTask:

  • Peningkatan performa
  • Meningkatkan fleksibilitas implementasi


Jadi, apa saja angka di balik peningkatan kinerja? Perhatikan kode ini:


Jika kita menjalankan kode ini, dibutuhkan 120ns untuk mengeksekusi JIT. Sekarang, jika kita mengganti Task dengan ValueTask seperti ini:

Dengan JIT, kita akan mendapatkan waktu eksekusi 65ns. Sekarang, memang benar bahwa karena Task.Delay kami tidak mengeksekusi secara sinkron, tetapi kami melihat peningkatan dalam waktu eksekusi.

Manfaat lain yang kami sebutkan adalah peningkatan fleksibilitas dalam implementasi. Sekarang, apa sebenarnya artinya ini? Nah, implementasi antarmuka asinkron yang harus disinkronkan akan dipaksa untuk menggunakan Task.Run atau Task.FromResult. Tentu saja, hal ini mengarah pada masalah kinerja yang kita bahas sebelumnya. Saat kita menggunakan ValueTask, kita lebih cenderung memilih antara implementasi sinkron atau asinkron. Perlu diingat bahwa ini bisa menjadi tanda bahwa kode Anda mungkin tidak dirancang dengan baik jika ini terjadi pada Anda.

Misalnya, amati antarmuka ini:


Katakanlah Anda ingin memanggilnya dari kode seperti ini:

Karena kami menggunakan ValueTask di antarmuka, implementasi antarmuka dapat sinkron atau asinkron. Kita bisa mendapatkan manfaat ini dengan pada dasarnya melewatkan penambahan beberapa fungsi ke IThing yang menangani perilaku sinkronisasi. Jauh lebih mudah untuk menggunakan antarmuka ini dengan cara ini. Berikut adalah implementasi sinkron dari antarmuka di atas:

Berikut adalah implementasi asinkron dari antarmuka yang sama:

Namun, kita harus mempertimbangkan beberapa trade-off sebelum menggunakan ValueTask. Sangat mudah untuk berpikir bahwa ValueTask harus digunakan secara default alih-alih Task, yang tentu saja tidak terjadi. Misalnya, meskipun ValueTask membantu kami menghindari penetapan yang tidak perlu saat sinkronisasi hasil tersedia, ValueTask juga berisi dua bidang.

Penting untuk diingat bahwa ini adalah struktur yang kita gunakan di sini, yang berarti kita menggunakan jenis nilai dan semua bebannya. Tugas, di sisi lain, adalah jenis referensi dengan hanya satu bidang.Saat Anda menggunakan ValueTask, kami memiliki lebih banyak data untuk diproses dan diproses. Jika metode seperti itu ditunggu dalam metode asinkron, maka metode asinkron adalahMesin negara juga akan lebih besar, karena menyimpan seluruh struktur biasanya membutuhkan lebih banyak ruang daripada menyimpan satu referensi.

Itu sebabnya orang-orang di Microsoft benar-benar merekomendasikan penggunaan Tugas atau Tugas sebagai jenis pengembalian default untuk metode asinkron. Hanya setelah analisis performa, Anda harus mempertimbangkan untuk beralih ke ValueTask.


ringkasan

ValueTask adalah struktur yang diperkenalkan di .NET 4.7 yang memberi kita banyak kemungkinan untuk menggunakan metode asinkron di .NET. Namun, itu bukan tanpa harga. Ini berguna untuk metode penting performa yang dijalankan secara sinkron. Dengan mereka kita dapat menghindari penetapan objek yang tidak perlu. Namun, sebagai tipe nilai, itu datang dengan semua masalah yang biasanya dimiliki tipe nilai. Oleh karena itu, kita bisa mendapatkan manfaat dari struktur ini, tetapi kita harus berhati-hati.

Alamat asli:Login hyperlink terlihat.




Mantan:【Tindakan Praktis】Gunakan Docker untuk membangun server VPN IPsec
Depan:Beralih menggunakan OpenConnect alih-alih Cisco AnyConnect untuk menghindari kunci meja perutean
Dipaparkan pada 2022-3-18 22:21:57 |
Datang untuk belajar lagi.
Dipaparkan pada 2022-3-22 14:05:53 |
Pelajari esensi pembelajaranTidak buruk
Sanggahan:
Semua perangkat lunak, materi pemrograman, atau artikel yang diterbitkan oleh Code Farmer Network hanya untuk tujuan pembelajaran dan penelitian; Konten di atas tidak boleh digunakan untuk tujuan komersial atau ilegal, jika tidak, pengguna akan menanggung semua konsekuensi. Informasi di situs ini berasal dari Internet, dan sengketa hak cipta tidak ada hubungannya dengan situs ini. Anda harus sepenuhnya menghapus konten di atas dari komputer Anda dalam waktu 24 jam setelah pengunduhan. Jika Anda menyukai program ini, harap dukung perangkat lunak asli, pembelian pendaftaran, dan dapatkan layanan asli yang lebih baik. Jika ada pelanggaran, silakan hubungi kami melalui email.

Mail To:help@itsvse.com