Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
adalah SpanOwner<T> jenis buffer hanya tumpukan yang menyewa buffer dari kumpulan memori bersama. Ini pada dasarnya mencerminkan fungsionalitas MemoryOwner<T>, tetapi sebagai ref struct jenis. Ini sangat berguna untuk buffer berumur pendek yang hanya digunakan dalam kode sinkron (yang tidak memerlukan Memory<T> instans), serta kode yang berjalan dalam perulangan yang ketat, karena membuat SpanOwner<T> nilai tidak akan memerlukan alokasi memori sama sekali.
API Platform:
SpanOwner<T>,MemoryOwner<T>
Sintaks
Fitur MemoryOwner<T> inti yang sama berlaku untuk jenis ini juga, dengan pengecualian itu menjadi tumpukan-saja struct, dan fakta bahwa ia tidak memiliki IMemoryOwner<T>interface implementasi, serta Memory<T> properti. Sintaks hampir identik dengan yang digunakan dengan MemoryOwner<T> juga, kecuali untuk perbedaan yang disebutkan di atas.
Sebagai contoh, misalkan kita memiliki metode di mana kita perlu mengalokasikan buffer sementara dengan ukuran tertentu (mari kita sebut nilai lengthini ), dan kemudian menggunakannya untuk melakukan beberapa pekerjaan. Versi pertama yang tidak efisien mungkin terlihat seperti ini:
byte[] buffer = new byte[length];
// Use buffer here
Ini tidak ideal, karena kami mengalokasikan buffer baru setiap kali kode ini digunakan, dan kemudian membuangnya segera (seperti yang disebutkan dalam MemoryOwner<T> dokumen juga), yang menempatkan lebih banyak tekanan pada pengumpul sampah. Kita dapat mengoptimalkan kode di atas dengan menggunakan ArrayPool<T>:
// Using directive to access the ArrayPool<T> type
using System.Buffers;
int[] buffer = ArrayPool<int>.Shared.Rent(length);
try
{
// Slice the span, as it might be larger than the requested size
Span<int> span = buffer.AsSpan(0, length);
// Use the span here
}
finally
{
ArrayPool<int>.Shared.Return(buffer);
}
Kode di atas menyewa buffer dari kumpulan array, tetapi lebih verbose dan rawan kesalahan: kita perlu berhati-hati dengan try/finally blok untuk memastikan untuk selalu mengembalikan buffer yang disewa ke kumpulan. Kita dapat menulis ulang dengan menggunakan jenisnya SpanOwner<T> , seperti:
// Be sure to include this using at the top of the file:
using Microsoft.Toolkit.HighPerformance.Buffers;
using SpanOwner<int> buffer = SpanOwner<int>.Allocate(length);
Span<int> span = buffer.Span;
// Use the span here, no slicing necessary
SpanOwner<T> Instans akan secara internal menyewa array, dan akan mengurus mengembalikannya ke kumpulan ketika keluar dari cakupan. Kita tidak perlu lagi menggunakan try/finally blok, karena pengkompilasi C# akan menambahkannya secara otomatis saat memperluas pernyataan tersebut using . Dengan demikian, jenisnya SpanOwner<T> dapat dilihat sebagai pembungkus ringan di sekitar ArrayPool<T> API, yang membuatnya lebih ringkas dan lebih mudah digunakan, mengurangi jumlah kode yang perlu ditulis untuk menyewa dan membuang buffer berumur pendek dengan benar. Anda dapat melihat cara menggunakan SpanOwner<T> membuat kode jauh lebih pendek dan lebih mudah.
Catatan
Karena ini adalah jenis tumpukan-saja, ini bergantung pada pola jenis IDisposable bebek yang diperkenalkan dengan C# 8. Itu ditunjukkan dalam sampel di atas: SpanOwner<T> jenis sedang digunakan dalam using blok meskipun fakta bahwa jenis tidak mengimplementasikan IDisposable antarmuka sama sekali, dan juga tidak pernah dikotak. Fungsionalitasnya sama: segera setelah buffer keluar dari cakupan, fungsionalitas secara otomatis dibuang. API mengandalkan SpanOwner<T> pola ini untuk performa ekstra: mereka menganggap bahwa buffer yang mendasar tidak akan pernah dibuang selama SpanOwner<T> jenisnya berada dalam cakupan, dan mereka tidak melakukan pemeriksaan tambahan yang dilakukan MemoryOwner<T> untuk memastikan bahwa buffer sebenarnya masih tersedia sebelum mengembalikan Memory<T> instans atau Span<T> darinya. Dengan demikian, jenis ini harus selalu digunakan dengan using blok atau ekspresi. Tidak melakukannya akan menyebabkan buffer yang mendasar tidak dikembalikan ke kumpulan bersama. Secara teknis hal yang sama juga dapat dicapai dengan memanggil DisposeSpanOwner<T> jenis secara manual (yang tidak memerlukan C# 8), tetapi itu rawan kesalahan dan karenanya tidak disarankan.
Contoh
Anda dapat menemukan lebih banyak contoh dalam pengujian unit.
.NET Community Toolkit