Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
SpanOwner<T> sınıfı, paylaşılan bir bellek havuzundan bellek tamponları kiralayan, yalnızca yığın için olan bir tampon türüdür. Esasen MemoryOwner<T> işlevselliğini yansıtır, ancak bir ref struct türü olarak. Bu işlevsellik, yalnızca senkron kodda kullanılan (örnek gerektirmeyen Memory<T>) kısa ömürlü arabellekler ve sıkı bir döngüde çalışan kod için özellikle kullanışlıdır.
SpanOwner<T> değerler oluşturmak için bellek ayırması gerekmez.
Platform API'leri:
SpanOwner<T>,MemoryOwner<T>
Sözdizimi
Aynı temel özellikleri MemoryOwner<T> bu tür için de geçerlidir, ancak sadece yığın tabanlı struct olması dışında. MemoryOwner<T>kullanılan söz dizimiyle neredeyse aynıdır.
Örneğin, belirli bir boyutta geçici bir arabellek ayırmanız gereken bir metoda sahip olduğunuzu varsayalım (bu değeri length olarak adlandıralım) ve ardından bunu kullanarak biraz işlem gerçekleştirmek için kullanılır. İlk, verimsiz sürüm şu şekilde görünebilir:
byte[] buffer = new byte[length];
// Use buffer here
Bu sürüm ideal değildir çünkü bu kodu her kullandığınızda yeni bir arabellek ayırır ve ardından hemen çöpe atar. Bu yaklaşım çöp toplayıcı üzerinde daha fazla baskı oluşturur. kullanarak ArrayPool<T>önceki kodu iyileştirebilirsiniz:
// 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);
}
Önceki kod, bir dizi havuzundan bir arabellek kiralar, ancak daha ayrıntılıdır ve hata yapmaya daha meyillidir. Kiralanan arabelleği her zaman havuza geri döndürdüğünüzden emin olmak için try/finally blokta dikkatli olmanız gerekir.
SpanOwner<T> türünü kullanarak bunu şu şekilde yeniden yazabilirsiniz:
// 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
Örnek SpanOwner<T> dahili olarak bir dizi kiralar ve kapsamın dışına çıktığında bunu havuza döndürmeyi üstlenir. C# derleyicisi bu deyimi genişletirken try/finally bunu otomatik olarak eklediğinden artık bir using blok da kullanmanız gerekmez. Bu nedenle, SpanOwner<T> API'leri etrafında ArrayPool<T> türünü basit bir sarmalayıcı olarak görebilirsiniz. Hem daha kompakt hem de kullanımı kolay hale getirerek kısa ömürlü tamponları düzgün bir şekilde kiralamak ve atmak için yazmanız gereken kod miktarını azaltır. Kullanımın SpanOwner<T> kodu çok daha kısa ve daha kolay hale getirdiğini görebilirsiniz.
Not
Bu tür yalnızca yığınla çalışır ve C# 8 ile tanıtılan ördek tipine sahip IDisposable desenine dayanır. Bu desen önceki örnekte gösterilmiştir: SpanOwner<T> türü, using arabirimini hiç uygulamıyor olmasına rağmen bir IDisposable blok içinde kullanılır ve aynı zamanda hiç kutulanmaz. Fonksiyon aynı şekilde çalışır: tampon belleği kapsam dışına çıkar çıkmaz otomatik olarak yok edilir.
SpanOwner<T> içindeki API'ler, ek performans için bu şablonu kullanır: SpanOwner<T> türü kapsam dahilinde olduğu sürece temel arabelleğin hiçbir zaman serbest bırakılmadığını varsayarlar.
MemoryOwner<T> veya Memory<T> örneği döndürmeden önce arabelleğin hala kullanılabilir olduğundan emin olmak için yapılan ek denetimleri gerçekleştirmezler. Bu nedenle, bu türü her zaman bir using blok veya ifadeyle kullanın. Bunun yapılmaması, altta yatan arabelleğin paylaşılan havuza geri döndürülmemesine neden olur. Teknik olarak, türünü el ile çağırarak DisposeSpanOwner<T> (C# 8 gerektirmez) aynı sonucu elde edebilirsiniz, ancak bu yaklaşım hataya açıktır ve bu nedenle önerilmez.
Örnekler
.NET Community Toolkit