C# Span (Geliştiriciler İçin Nasıl Çalışır)
Span, C# 7.2'de System ad alanındaki Span yapısının bir parçası olarak tanıtılan bir türdür. Rastgele bellek birimlerinin kesintisiz bir bölgesini temsil etmek için tasarlanmıştır. Diziler veya yönetilen yığın gibi koleksiyonların aksine, Span yığında bulunan bellek veya işaret ettiği bellek bölgesine sahip değildir; bunun yerine mevcut bellek blokları üzerinde hafif bir görünüm sağlar. Bu özelliği, fazla yük ve güvensiz kod senaryolarına neden olmadan, bellek tamponları üzerinde etkili bir şekilde çalışmanız gereken senaryolarda Span'ı özellikle güçlü kılar. Bu makalenin ilerleyen bölümlerinde, IronPDF kütüphanesi'nin Iron Software tarafından tanıtımını da göreceğiz.
Span'ın Ana Özellikleri
1. Bellek Yönetimi
C# dilinde Span, geliştiricilerin doğrudan bellekle çalışmasına, geleneksel yığın tahsislerine başvurmadan izin verir. Mevcut diziler veya diğer bellek kaynaklarından bellek dilimleri oluşturmanın bir yolunu sunar, ek bellek kopyalarına olan ihtiyacı ortadan kaldırır.
2. Sıfır Kopyalama Soyutlamaları
C# Span'ın öne çıkan özelliklerinden biri sıfır kopyalama soyutlamalarıdır. Verileri kopyalamak yerine, Span mevcut belleği verimli bir şekilde referans almanın bir yolunu sağlar. Bu, özellikle büyük miktarda verinin kopyalanmasının pratik olmadığı ya da çok maliyetli olduğu senaryolarda faydalıdır.
3. İşaretçi Benzeri İşlemler
C# dili geleneksel olarak yüksek seviyeli, güvenli bir dil olmakla beraber, Span, C veya C++ dillerinde işaretçilerle çalışmaya benzer düşük seviyede bellek manipülasyonu derecesine sahiptir. Geliştiriciler, C#'ın güvenli ve yönetilen yapısından ödün vermeden işaretçi benzeri işlemler gerçekleştirebilirler.
4. Değiştirilemez Doğa
Düşük seviyeli bellek erişim kabiliyetlerine rağmen, C# Span değiştirilemez bir yapı olarak kalır. Bu, bellek manipülasyonuna izin verse de, istenmeyen değişikliklerin önüne geçerek güvenliği sağlar.
Örnek
using System;
class Program
{
static void Main()
{
int[] array = { 1, 2, 3, 4, 5 };
// Create a span that points to the entire array
Span<int> span = array;
// Modify the data using the span
span[2] = 10;
// Print the modified array
foreach (var item in array)
{
Console.WriteLine(item);
}
}
}
using System;
class Program
{
static void Main()
{
int[] array = { 1, 2, 3, 4, 5 };
// Create a span that points to the entire array
Span<int> span = array;
// Modify the data using the span
span[2] = 10;
// Print the modified array
foreach (var item in array)
{
Console.WriteLine(item);
}
}
}
Imports System
Friend Class Program
Shared Sub Main()
Dim array() As Integer = { 1, 2, 3, 4, 5 }
' Create a span that points to the entire array
Dim span As Span(Of Integer) = array
' Modify the data using the span
span(2) = 10
' Print the modified array
For Each item In array
Console.WriteLine(item)
Next item
End Sub
End Class
ReadOnlySpan
Span değiştirebilir olup alttaki veriyi değiştirmeye izin verirken, ReadOnlySpan belleğin değiştirilemez bir görünümüdür. Verileri değiştirme ihtiyacınız olmadığı senaryolar için uygun hale getirir çünkü kesintisiz bir bellek bölgesine salt okunur bir arayüz sunar.
Burada bazı ana noktalar:
1. Salt Okunur Görünüm
Adından da anlaşılacağı gibi, ReadOnlySpan, bir bellek bloğunun salt okunur bir görünümünü oluşturmanıza olanak tanır. Bu, ReadOnlySpan aracılığıyla elemanları değiştiremeyeceğiniz anlamına gelir.
2. Bellek Temsili
Span gibi, ReadOnlySpan de işaret ettiği belleğe sahip değildir. Mevcut belleği referans alır ve dizilere, yığın tahsisli belleğe veya yerel belleğe işaret edebilir.
3. Performans Avantajları
Span gibi, ReadOnlySpan, özellikle büyük miktarda veriyi işlerken, daha iyi performans sunabilir; kopyalama gereksinimini azaltır.
4. Sınır Kontrolü Yoktur
Span gibi, ReadOnlySpan sınır kontrolü yapmaz. İşlemlerin, altta yatan bellek sınırları içerisinde kalmasını sağlamak geliştiricinin sorumluluğundadır.
5. Dizi Dilimleme ile Kullanımı
ReadOnlySpan dilimlemeyi destekler, bu da orijinal belleğin bir kısmına atıfta bulunan alt dilimler oluşturmanıza olanak tanır.
Örnek
using System;
class Program
{
static void Main()
{
int[] array = { 1, 2, 3, 4, 5 };
// Create a read-only span that points to the entire array
ReadOnlySpan<int> readOnlySpan = array;
// Access and print the data through the read-only span
foreach (var item in readOnlySpan)
{
Console.WriteLine(item);
}
// Note: The following line would result in a compilation error since readOnlySpan is read-only.
// readOnlySpan[2] = 10;
}
}
using System;
class Program
{
static void Main()
{
int[] array = { 1, 2, 3, 4, 5 };
// Create a read-only span that points to the entire array
ReadOnlySpan<int> readOnlySpan = array;
// Access and print the data through the read-only span
foreach (var item in readOnlySpan)
{
Console.WriteLine(item);
}
// Note: The following line would result in a compilation error since readOnlySpan is read-only.
// readOnlySpan[2] = 10;
}
}
Imports System
Friend Class Program
Shared Sub Main()
Dim array() As Integer = { 1, 2, 3, 4, 5 }
' Create a read-only span that points to the entire array
Dim readOnlySpan As ReadOnlySpan(Of Integer) = array
' Access and print the data through the read-only span
For Each item In readOnlySpan
Console.WriteLine(item)
Next item
' Note: The following line would result in a compilation error since readOnlySpan is read-only.
' readOnlySpan[2] = 10;
End Sub
End Class
ReadOnlySpan oluşturmak ve onunla çalışmak için birçok farklı yol vardır. Aşağıda bazı örnekler bulunmaktadır.
1. String'den ReadOnlySpan Üretmek
string msg = "Hello, World!";
ReadOnlySpan<char> span1 = msg.AsSpan();
// Read-only manipulation
char firstChar = span1[0];
Console.WriteLine(firstChar); // Outputs: H
string msg = "Hello, World!";
ReadOnlySpan<char> span1 = msg.AsSpan();
// Read-only manipulation
char firstChar = span1[0];
Console.WriteLine(firstChar); // Outputs: H
Dim msg As String = "Hello, World!"
Dim span1 As ReadOnlySpan(Of Char) = msg.AsSpan()
' Read-only manipulation
Dim firstChar As Char = span1(0)
Console.WriteLine(firstChar) ' Outputs: H
2. Alt Dizilerle Çalışma
ReadOnlySpanSlice kullanın
// Example usage of Slice method on ReadOnlySpan<char>
ReadOnlySpan<char> spanFromString = "Sample String".AsSpan();
ReadOnlySpan<char> substringSpan = spanFromString.Slice(7, 6); // Extracts 'String'
// Example usage of Slice method on ReadOnlySpan<char>
ReadOnlySpan<char> spanFromString = "Sample String".AsSpan();
ReadOnlySpan<char> substringSpan = spanFromString.Slice(7, 6); // Extracts 'String'
' Example usage of Slice method on ReadOnlySpan<char>
Dim spanFromString As ReadOnlySpan(Of Char) = "Sample String".AsSpan()
Dim substringSpan As ReadOnlySpan(Of Char) = spanFromString.Slice(7, 6) ' Extracts 'String'
3. Alt Diziyi Bir Yönteme Geçirmek
Yönteme parametre olarak ReadOnlySpan
void ProcessSubstringfromReadOnlySpan(ReadOnlySpan<char> substring)
{
// Perform operations on the substring
}
// Usage
ReadOnlySpan<char> spanFromString = "Sample String".AsSpan();
ProcessSubstringfromReadOnlySpan(spanFromString.Slice(7, 6));
void ProcessSubstringfromReadOnlySpan(ReadOnlySpan<char> substring)
{
// Perform operations on the substring
}
// Usage
ReadOnlySpan<char> spanFromString = "Sample String".AsSpan();
ProcessSubstringfromReadOnlySpan(spanFromString.Slice(7, 6));
Private Sub ProcessSubstringfromReadOnlySpan(ByVal substring As ReadOnlySpan(Of Char))
' Perform operations on the substring
End Sub
' Usage
Private spanFromString As ReadOnlySpan(Of Char) = "Sample String".AsSpan()
ProcessSubstringfromReadOnlySpan(spanFromString.Slice(7, 6))
4. Bir Dizgiyi İçinde Arama Yapma
Bir dize içinde arama yapmak için ReadOnlySpanIndexOf() kullanımı.
ReadOnlySpan<char> stringSpan = "Hello, World!".AsSpan();
int index = stringSpan.IndexOf('W');
Console.WriteLine(index); // Outputs: 7
ReadOnlySpan<char> stringSpan = "Hello, World!".AsSpan();
int index = stringSpan.IndexOf('W');
Console.WriteLine(index); // Outputs: 7
Dim stringSpan As ReadOnlySpan(Of Char) = "Hello, World!".AsSpan()
Dim index As Integer = stringSpan.IndexOf("W"c)
Console.WriteLine(index) ' Outputs: 7
5. Bellek Haritalı Dosyaları Kullanma
ReadOnlySpan
using System;
using System.IO.MemoryMappedFiles;
class Program
{
static void ProcessData(ReadOnlySpan<byte> data)
{
// Process data directly from the memory-mapped file
}
static void Main()
{
using (var memmf = MemoryMappedFile.CreateFromFile("data.bin"))
{
using (var accessor = memmf.CreateViewAccessor())
{
byte[] buffer = new byte[accessor.Capacity];
accessor.ReadArray(0, buffer, 0, buffer.Length);
ReadOnlySpan<byte> dataSpan = new ReadOnlySpan<byte>(buffer);
ProcessData(dataSpan);
}
}
}
}
using System;
using System.IO.MemoryMappedFiles;
class Program
{
static void ProcessData(ReadOnlySpan<byte> data)
{
// Process data directly from the memory-mapped file
}
static void Main()
{
using (var memmf = MemoryMappedFile.CreateFromFile("data.bin"))
{
using (var accessor = memmf.CreateViewAccessor())
{
byte[] buffer = new byte[accessor.Capacity];
accessor.ReadArray(0, buffer, 0, buffer.Length);
ReadOnlySpan<byte> dataSpan = new ReadOnlySpan<byte>(buffer);
ProcessData(dataSpan);
}
}
}
}
Imports System
Imports System.IO.MemoryMappedFiles
Friend Class Program
Private Shared Sub ProcessData(ByVal data As ReadOnlySpan(Of Byte))
' Process data directly from the memory-mapped file
End Sub
Shared Sub Main()
Using memmf = MemoryMappedFile.CreateFromFile("data.bin")
Using accessor = memmf.CreateViewAccessor()
Dim buffer(accessor.Capacity - 1) As Byte
accessor.ReadArray(0, buffer, 0, buffer.Length)
Dim dataSpan As New ReadOnlySpan(Of Byte)(buffer)
ProcessData(dataSpan)
End Using
End Using
End Sub
End Class
6. Verimli Dize Manipülasyonu
ReadOnlySpan
Span<char> newSpan = new char[6];
ReadOnlySpan<char> spanFromString = "Sample String".AsSpan().Slice(7, 6);
spanFromString.CopyTo(newSpan);
Console.WriteLine(new string(newSpan)); // Outputs: String
Span<char> newSpan = new char[6];
ReadOnlySpan<char> spanFromString = "Sample String".AsSpan().Slice(7, 6);
spanFromString.CopyTo(newSpan);
Console.WriteLine(new string(newSpan)); // Outputs: String
Dim newSpan As Span(Of Char) = New Char(5){}
Dim spanFromString As ReadOnlySpan(Of Char) = "Sample String".AsSpan().Slice(7, 6)
spanFromString.CopyTo(newSpan)
Console.WriteLine(New String(newSpan)) ' Outputs: String
7. Alt Diziyi API'lere Geçme
Karakter aralıkları üzerinde çalışan harici kütüphaneler veya API'lerle çalışırken.
void ExternalApiMethod(ReadOnlySpan<char> data)
{
// Call the external API with the character span
}
// Usage
ReadOnlySpan<char> spanFromString = "Sample String".AsSpan();
ExternalApiMethod(spanFromString.Slice(7, 6));
void ExternalApiMethod(ReadOnlySpan<char> data)
{
// Call the external API with the character span
}
// Usage
ReadOnlySpan<char> spanFromString = "Sample String".AsSpan();
ExternalApiMethod(spanFromString.Slice(7, 6));
Private Sub ExternalApiMethod(ByVal data As ReadOnlySpan(Of Char))
' Call the external API with the character span
End Sub
' Usage
Private spanFromString As ReadOnlySpan(Of Char) = "Sample String".AsSpan()
ExternalApiMethod(spanFromString.Slice(7, 6))
ReadOnlySpan
Span'ın Sınırlamaları
Span, C# dilinde güçlü bir özellik ve birçok avantaj sunar, ancak kesintisiz ve kesintili bellek bağlamında belirli sınırlamalar ve dikkate alınması gereken hususlar vardır. Bu sınırlamaları keşfedelim:
1. Kesintisiz Bellek Tamponları
1.1 Otomatik Bellek Yönetimi Yoktur
Span, işaret ettiği belleği yönetmez. Bu, alttaki yönetilen bellek serbest bırakılırsa veya kapsam dışına çıkarsa, Span kullanmanın tanımsız davranışa veya potansiyel çöküşlere neden olacağı anlamına gelir. Geliştiriciler, Span kullanırken, alttaki belleğin hala geçerli olduğundan emin olmalıdır.
1.2 Çöp Toplama Yoktur
Span belleğe sahip olmadığından, çöp toplanmasına tabi değildir. Bu nedenle, yığın (stack) üzerinde tahsis edilmiş bellekle veya Span 'den daha kısa ömürlü bir bellekle çalışırken dikkatli olmanız gerekir.
1.3 Sınır Kontrolü Devre Dışıdır
Span ve ReadOnlySpan, varsayılan olarak sınır kontrolü yapmaz. Dikkatle kullanılmadığında geçersiz bellek lokasyonlarına erişime neden olabilir. Geliştiriciler, Span üzerindeki işlemlerin alttaki belleğin sınırları içinde kalmasını manuel olarak sağlamalıdır.
1.4 Kesintili Bellek için Destek Yoktur
Span, ardışık bellekle çalışacak şekilde tasarlanmıştır. Eğer ardışık olmayan belleğiniz varsa veya daha karmaşık veri yapıları temsil etmeniz gerekiyorsa, Span en uygun seçenek olmayabilir.
1.5 Tüm İşlemler Desteklenmez
Span, dilimleme, indeksleme ve yineleme gibi birçok yaygın işlemi desteklese de, tüm işlemler desteklenmez. Örneğin, bir Span'yi yeniden boyutlandıramazsınız ve alttaki belleğin uzunluğunu değiştiren belirli işlemler izin verilmez.
1.6 Sınırlı Platform Uyumluluğu
Span, .NET Standard ve .NET Core'un bir parçası olmasına rağmen, tüm platformlarda veya ortamlarda mevcut olmayabilir. Kodunuzda kullanmayı planlıyorsanız, hedef platformunuzun Span'yi desteklediğinden emin olmak önemlidir.
2. Kesintili Bellek Tamponları
2.1 Kesintili Bellek için Sınırlı Destek
ReadOnlySpan, öncelikle ardışık bellek blokları veya tamponlarla sorunsuz çalışacak şekilde tasarlanmıştır. Bellekte boşluklar içeren kesintili bellek tamponları veya yapıları içeren senaryolar için en uygun seçim olmayabilir.
2.2 Yapısal Sınırlamalar
Ardışık olmayan belleğe dayanan belirli veri yapıları veya senaryolar, ReadOnlySpan ile iyi uyum sağlamayabilir. Örneğin, bağlı listeler veya grafik yapılar gibi veri yapıları, ReadOnlySpan'nin ardışık bellek gereksinimi nedeniyle iyi uygun olmayabilir.
2.3 Karmaşık İşaretçi İşlemleri
Özellikle karmaşık işaretçi aritmetiği gerektiren ardışık olmayan bellekle ilgili durumlarda, ReadOnlySpan, C++ gibi dillerdeki ham işaretçiler kadar düşük seviyeli kontrol ve esneklik sunmayabilir. Bu tür durumlarda, işaretçilerle güvensiz kod kullanmak daha uygun olabilir.
2.4 Bazı API'lerde Doğrudan Destek Eksikliği
Ardışık bellek gibi, tüm API'ların veya kütüphanelerin, ReadOnlySpan ile temsil edilen ardışık olmayan belleği doğrudan desteklemeyebileceğini unutmayın. Bu tür senaryolara uyum sağlamak, uyumluluğu garantilemek için ek ara adımlar veya dönüştürmeler gerektirebilir.
Span ve Yönetilmeyen Bellek
C# dilinde, Span, yönetilmeyen bellekle etkin bir şekilde kullanılabilir, bellekle ilgili işlemleri kontrol altında ve verimli bir şekilde gerçekleştirebilir. Yönetilmeyen bellek, .NET çalıştırma ortamının bellek toplayıcısı tarafından yönetilmeyen bellektir ve genellikle yerel bellek tahsisleri ve serbest bırakma işlemlerini içerir. C# dilinde Span, yönetilmeyen bellekle şu şekilde kullanılabilir.
Yönetilmeyen Belleği Ayırma
Yönetilmeyen bellek ayırmak için System.Runtime.InteropServices.MemoryMarshal sınıfını kullanabilirsiniz. Marshal.AllocHGlobal yöntemi bellek ayırır ve ayrılan bloğa bir işaretçi döndürür. Ayrılan bellek veya bellek adresi, bir unmanagedMemory işaretçisinde tutulur ve okuma-yazma erişimi olacaktır. Belleğin bitişik bölgelerine kolayca erişilebilir.
using System;
using System.Runtime.InteropServices;
class Program
{
static void Main()
{
const int bufferSize = 100;
IntPtr unmanagedMemory = Marshal.AllocHGlobal(bufferSize);
// Create a Span from the unmanaged memory
Span<byte> span = new Span<byte>(unmanagedMemory.ToPointer(), bufferSize);
// Use the Span as needed...
// Don't forget to free the unmanaged memory when done
Marshal.FreeHGlobal(unmanagedMemory);
}
}
using System;
using System.Runtime.InteropServices;
class Program
{
static void Main()
{
const int bufferSize = 100;
IntPtr unmanagedMemory = Marshal.AllocHGlobal(bufferSize);
// Create a Span from the unmanaged memory
Span<byte> span = new Span<byte>(unmanagedMemory.ToPointer(), bufferSize);
// Use the Span as needed...
// Don't forget to free the unmanaged memory when done
Marshal.FreeHGlobal(unmanagedMemory);
}
}
Imports System
Imports System.Runtime.InteropServices
Friend Class Program
Shared Sub Main()
Const bufferSize As Integer = 100
Dim unmanagedMemory As IntPtr = Marshal.AllocHGlobal(bufferSize)
' Create a Span from the unmanaged memory
Dim span As New Span(Of Byte)(unmanagedMemory.ToPointer(), bufferSize)
' Use the Span as needed...
' Don't forget to free the unmanaged memory when done
Marshal.FreeHGlobal(unmanagedMemory)
End Sub
End Class
Yukarıdaki kaynak kodunda, Marshal.AllocHGlobal kullanarak yönetilmeyen bir bellek bloğu tahsis ediyoruz ve ardından yönetilmeyen bellekten elde edilen işaretçi ile bir Span<byte> oluşturuyoruz. Bu, tanıdık Span API'sini kullanarak yönetilmeyen bellekle çalışmamıza olanak sağlar. Yönetilmeyen bellekle çalışırken, belleğin ayırma ve ayırmama yönetiminden siz sorumlusunuz, bu not edilmesi önemli bir konudur.
Yönetilmeyen Belleğe ve Bellekten Veri Kopyalama
Span, yönetilen ve yönetilmeyen bellek arasında verileri verimli bir şekilde kopyalamak için kullanılabilecek Slice, CopyTo ve ToArray gibi yöntemler sağlar.
using System;
using System.Runtime.InteropServices;
class Program
{
static void Main()
{
// Managed array to copy data from
int[] sourceArray = { 1, 2, 3, 4, 5 };
// Allocate unmanaged memory for the destination data
IntPtr destinationPointer = Marshal.AllocHGlobal(sourceArray.Length * sizeof(int));
try
{
// Create a Span<int> from the source array
Span<int> sourceSpan = sourceArray;
// Create a Span<int> from the allocated unmanaged memory
Span<int> destinationSpan = new Span<int>(destinationPointer.ToPointer(), sourceArray.Length);
// Copy data from the source Span<int> to the destination Span<int>
sourceSpan.CopyTo(destinationSpan);
// Print the values in the destination memory
Console.WriteLine("Values in the destination memory:");
foreach (var value in destinationSpan)
{
Console.Write($"{value} ");
}
}
finally
{
// Deallocate the unmanaged memory when done
Marshal.FreeHGlobal(destinationPointer);
}
}
}
using System;
using System.Runtime.InteropServices;
class Program
{
static void Main()
{
// Managed array to copy data from
int[] sourceArray = { 1, 2, 3, 4, 5 };
// Allocate unmanaged memory for the destination data
IntPtr destinationPointer = Marshal.AllocHGlobal(sourceArray.Length * sizeof(int));
try
{
// Create a Span<int> from the source array
Span<int> sourceSpan = sourceArray;
// Create a Span<int> from the allocated unmanaged memory
Span<int> destinationSpan = new Span<int>(destinationPointer.ToPointer(), sourceArray.Length);
// Copy data from the source Span<int> to the destination Span<int>
sourceSpan.CopyTo(destinationSpan);
// Print the values in the destination memory
Console.WriteLine("Values in the destination memory:");
foreach (var value in destinationSpan)
{
Console.Write($"{value} ");
}
}
finally
{
// Deallocate the unmanaged memory when done
Marshal.FreeHGlobal(destinationPointer);
}
}
}
Imports System
Imports System.Runtime.InteropServices
Friend Class Program
Shared Sub Main()
' Managed array to copy data from
Dim sourceArray() As Integer = { 1, 2, 3, 4, 5 }
' Allocate unmanaged memory for the destination data
Dim destinationPointer As IntPtr = Marshal.AllocHGlobal(sourceArray.Length * Len(New Integer()))
Try
' Create a Span<int> from the source array
Dim sourceSpan As Span(Of Integer) = sourceArray
' Create a Span<int> from the allocated unmanaged memory
Dim destinationSpan As New Span(Of Integer)(destinationPointer.ToPointer(), sourceArray.Length)
' Copy data from the source Span<int> to the destination Span<int>
sourceSpan.CopyTo(destinationSpan)
' Print the values in the destination memory
Console.WriteLine("Values in the destination memory:")
For Each value In destinationSpan
Console.Write($"{value} ")
Next value
Finally
' Deallocate the unmanaged memory when done
Marshal.FreeHGlobal(destinationPointer)
End Try
End Sub
End Class
Bu örnekte:
Marshal.AllocHGlobal, hedef veriler için yönetilmeyen belleği tahsis eder.new Span<int>(destinationPointer.ToPointer(), sourceArray.Length), tahsis edilen yönetilmeyen bellekten birSpan<int>oluşturur.sourceSpan.CopyTo(destinationSpan)yöntemi, verileri yönetilen diziden yönetilmeyen belleğe kopyalar.- Hedef bellekteki değerler, kopyalama işlemini doğrulamak için yazdırılır.
Marshal.FreeHGlobal(destinationPointer)yöntemi, iş bitince yönetilmeyen belleği ayırmak için kullanılır.
Güvenli Olmayan Kodu Kullanma
Yönetilmeyen bellekle uğraşırken, işaretçilerle birlikte güvenli olmayan kod da kullanabilirsiniz. Bu gibi durumlarda, Unsafe.AsPointer() yöntemi idaresi kullanılarak Span'dan bir işaretçi elde edebilirsiniz.
using System;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
class Program
{
static void Main()
{
const int bufferSize = 100;
IntPtr unmanagedMemory = Marshal.AllocHGlobal(bufferSize);
// Create a Span from the unmanaged memory
Span<byte> span = new Span<byte>(unmanagedMemory.ToPointer(), bufferSize);
// Use unsafe code to work with pointers
unsafe
{
byte* pointer = (byte*)Unsafe.AsPointer(ref MemoryMarshal.GetReference(span));
// Use the pointer as needed...
}
// Don't forget to free the unmanaged memory when done
Marshal.FreeHGlobal(unmanagedMemory);
}
}
using System;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
class Program
{
static void Main()
{
const int bufferSize = 100;
IntPtr unmanagedMemory = Marshal.AllocHGlobal(bufferSize);
// Create a Span from the unmanaged memory
Span<byte> span = new Span<byte>(unmanagedMemory.ToPointer(), bufferSize);
// Use unsafe code to work with pointers
unsafe
{
byte* pointer = (byte*)Unsafe.AsPointer(ref MemoryMarshal.GetReference(span));
// Use the pointer as needed...
}
// Don't forget to free the unmanaged memory when done
Marshal.FreeHGlobal(unmanagedMemory);
}
}
Imports System
Imports System.Runtime.InteropServices
Imports System.Runtime.CompilerServices
Friend Class Program
Shared Sub Main()
Const bufferSize As Integer = 100
Dim unmanagedMemory As IntPtr = Marshal.AllocHGlobal(bufferSize)
' Create a Span from the unmanaged memory
Dim span As New Span(Of Byte)(unmanagedMemory.ToPointer(), bufferSize)
' Use unsafe code to work with pointers
'INSTANT VB TODO TASK: C# 'unsafe' code is not converted by Instant VB:
' unsafe
' {
' byte* pointer = (byte*)Unsafe.AsPointer(ref MemoryMarshal.GetReference(span));
' ' Use the pointer as needed...
' }
' Don't forget to free the unmanaged memory when done
Marshal.FreeHGlobal(unmanagedMemory)
End Sub
End Class
Bu örnekte, Unsafe.AsPointer metodunu kullanarak Span'dan bir işaretçi elde ediyoruz. Bu, işaretçilerle doğrudan çalışırken güvenli olmayan kod kullanmamıza olanak tanır.
Yönetilmeyen bellekle çalışırken, bellek sızıntılarını önlemek için ayırma ve geri alma işlemlerini doğru bir şekilde yönetmek önemlidir. Her zaman uygun yöntemler kullanarak, örneğin Marshal.FreeHGlobal(), yönetilmeyen belleği serbest bırakın. Ayrıca, güvensiz kodu kullanırken dikkatli olunması gerektiğini unutmayın, çünkü yanlış idare edilirse potansiyel güvenlik riskleri doğurabilir.
Span ve Asenkron Metot Çağrıları
Span'i C# asenkron yöntem çağrıları ile birlikte kullanmak, özellikle büyük miktarda veri veya G/Ç işlemleri ile uğraşırken güçlü bir kombinasyondur. Amaç, verilerin gereksiz yere kopyalanmaması gereken asenkron işlemleri etkin bir şekilde ele almaktır. Asenkron senaryolarda Span'i nasıl kullanabileceğinizi keşfedelim:
1. Asenkron G/Ç İşlemleri:
Asenkron I/O işlemleri, örneğin bir akışa veri okuma veya yazma ile uğraşırken, ek tamponlar oluşturmadan verilerle verimli bir şekilde çalışmak için Memory veya Span kullanabilirsiniz.
using System;
using System.IO;
using System.Threading.Tasks;
class Program
{
static async Task ProcessDataAsync(Stream stream)
{
const int bufferSize = 4096;
byte[] buffer = new byte[bufferSize];
while (true)
{
int bytesRead = await stream.ReadAsync(buffer.AsMemory());
if (bytesRead == 0)
break;
// Process the data using Span without unnecessary copying
ProcessData(buffer.AsSpan(0, bytesRead));
}
}
static void ProcessData(Span<byte> data)
{
// Perform operations on the data
}
}
using System;
using System.IO;
using System.Threading.Tasks;
class Program
{
static async Task ProcessDataAsync(Stream stream)
{
const int bufferSize = 4096;
byte[] buffer = new byte[bufferSize];
while (true)
{
int bytesRead = await stream.ReadAsync(buffer.AsMemory());
if (bytesRead == 0)
break;
// Process the data using Span without unnecessary copying
ProcessData(buffer.AsSpan(0, bytesRead));
}
}
static void ProcessData(Span<byte> data)
{
// Perform operations on the data
}
}
Imports System
Imports System.IO
Imports System.Threading.Tasks
Friend Class Program
Private Shared Async Function ProcessDataAsync(ByVal stream As Stream) As Task
Const bufferSize As Integer = 4096
Dim buffer(bufferSize - 1) As Byte
Do
Dim bytesRead As Integer = Await stream.ReadAsync(buffer.AsMemory())
If bytesRead = 0 Then
Exit Do
End If
' Process the data using Span without unnecessary copying
ProcessData(buffer.AsSpan(0, bytesRead))
Loop
End Function
Private Shared Sub ProcessData(ByVal data As Span(Of Byte))
' Perform operations on the data
End Sub
End Class
Bu örnekte, ReadAsync metodu, arabelleğe bir akıştan asenkron olarak veri okur. Ardından ProcessData metodu, verileri başka bir arabelleğe kopyalamadan doğrudan Span
2. Asenkron Dosya İşlemleri:
G/Ç işlemlerine benzer şekilde, asenkron dosya işlemleriyle uğraşırken, Span kullanarak ek kopyalama yapmadan etkin bir şekilde verileri işleyebilirsiniz.
using System;
using System.IO;
using System.Threading.Tasks;
class Program
{
static async Task ProcessFileAsync(string filePath)
{
const int bufferSize = 4096;
using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
byte[] buffer = new byte[bufferSize];
while (true)
{
int bytesRead = await fileStream.ReadAsync(buffer.AsMemory());
if (bytesRead == 0)
break;
// Process the data using Span without unnecessary copying
ProcessData(buffer.AsSpan(0, bytesRead));
}
}
}
static void ProcessData(Span<byte> data)
{
// Perform operations on the data
}
}
using System;
using System.IO;
using System.Threading.Tasks;
class Program
{
static async Task ProcessFileAsync(string filePath)
{
const int bufferSize = 4096;
using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
byte[] buffer = new byte[bufferSize];
while (true)
{
int bytesRead = await fileStream.ReadAsync(buffer.AsMemory());
if (bytesRead == 0)
break;
// Process the data using Span without unnecessary copying
ProcessData(buffer.AsSpan(0, bytesRead));
}
}
}
static void ProcessData(Span<byte> data)
{
// Perform operations on the data
}
}
Imports System
Imports System.IO
Imports System.Threading.Tasks
Friend Class Program
Private Shared Async Function ProcessFileAsync(ByVal filePath As String) As Task
Const bufferSize As Integer = 4096
Using fileStream As New FileStream(filePath, FileMode.Open, FileAccess.Read)
Dim buffer(bufferSize - 1) As Byte
Do
Dim bytesRead As Integer = Await fileStream.ReadAsync(buffer.AsMemory())
If bytesRead = 0 Then
Exit Do
End If
' Process the data using Span without unnecessary copying
ProcessData(buffer.AsSpan(0, bytesRead))
Loop
End Using
End Function
Private Shared Sub ProcessData(ByVal data As Span(Of Byte))
' Perform operations on the data
End Sub
End Class
Burada, ReadAsync metodu bir dosya akışından arabelleğe veri okur ve ProcessData metodu verileri doğrudan Span
3. Asenkron Görev İşleme:
Veri üreten veya tüketen asenkron görevlerle çalışırken, gereksiz kopyalamalardan kaçınmak için Memory veya Span kullanabilirsiniz.
using System;
using System.Linq;
using System.Threading.Tasks;
class Program
{
static async Task<int> ProcessDataAsync(int[] data)
{
// Asynchronous processing of data
await Task.Delay(1000);
// Returning the length of the processed data
return data.Length;
}
static async Task Main()
{
int[] inputData = Enumerable.Range(1, 1000).ToArray();
// Process the data asynchronously without copying
int processedLength = await ProcessDataAsync(inputData.AsMemory());
Console.WriteLine($"Processed data length: {processedLength}");
}
}
using System;
using System.Linq;
using System.Threading.Tasks;
class Program
{
static async Task<int> ProcessDataAsync(int[] data)
{
// Asynchronous processing of data
await Task.Delay(1000);
// Returning the length of the processed data
return data.Length;
}
static async Task Main()
{
int[] inputData = Enumerable.Range(1, 1000).ToArray();
// Process the data asynchronously without copying
int processedLength = await ProcessDataAsync(inputData.AsMemory());
Console.WriteLine($"Processed data length: {processedLength}");
}
}
Imports System
Imports System.Linq
Imports System.Threading.Tasks
Friend Class Program
Private Shared Async Function ProcessDataAsync(ByVal data() As Integer) As Task(Of Integer)
' Asynchronous processing of data
Await Task.Delay(1000)
' Returning the length of the processed data
Return data.Length
End Function
Shared Async Function Main() As Task
Dim inputData() As Integer = Enumerable.Range(1, 1000).ToArray()
' Process the data asynchronously without copying
Dim processedLength As Integer = Await ProcessDataAsync(inputData.AsMemory())
Console.WriteLine($"Processed data length: {processedLength}")
End Function
End Class
Bu örnekte ProcessDataAsync metodu, verileri asenkron olarak işler ve ek kopyalama gerektirmeden işlenen verilerin uzunluğunu döndürür.
IronPDF Tanıtımı
IronPDF kütüphanesi genel bakış, Iron Software'den en son C# PDF kütüphanesidir ve C# kodu kullanılarak dinamik olarak güzel PDF belgeleri oluşturmak için kullanılabilir. IronPDF, HTML'den PDF oluşturma, HTML içeriğini PDF'ye dönüştürme, PDF dosyalarını birleştirme veya bölme gibi çeşitli özellikler sunar.
IronPDF'nin ana özelliği, düzenleri ve stilleri koruyan HTML'den PDF'ye dönüştürme işlevselliğidir. Web içeriğinden PDF'ler üretebilir, bu da onu raporlar, faturalar ve dökümantasyon için harika kılar. Bu araç, HTML dosyalarını, URL'leri ve HTML dizelerini PDF dosyalarına dönüştürmeyi destekler.
using IronPdf;
class Program
{
static void Main(string[] args)
{
var renderer = new ChromePdfRenderer();
// 1. Convert HTML String to PDF
var htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>";
var pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent);
pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf");
// 2. Convert HTML File to PDF
var htmlFilePath = "path_to_your_html_file.html"; // Specify the path to your HTML file
var pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath);
pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf");
// 3. Convert URL to PDF
var url = "http://ironpdf.com"; // Specify the URL
var pdfFromUrl = renderer.RenderUrlAsPdf(url);
pdfFromUrl.SaveAs("URLToPDF.pdf");
}
}
using IronPdf;
class Program
{
static void Main(string[] args)
{
var renderer = new ChromePdfRenderer();
// 1. Convert HTML String to PDF
var htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>";
var pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent);
pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf");
// 2. Convert HTML File to PDF
var htmlFilePath = "path_to_your_html_file.html"; // Specify the path to your HTML file
var pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath);
pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf");
// 3. Convert URL to PDF
var url = "http://ironpdf.com"; // Specify the URL
var pdfFromUrl = renderer.RenderUrlAsPdf(url);
pdfFromUrl.SaveAs("URLToPDF.pdf");
}
}
Imports IronPdf
Friend Class Program
Shared Sub Main(ByVal args() As String)
Dim renderer = New ChromePdfRenderer()
' 1. Convert HTML String to PDF
Dim htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>"
Dim pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent)
pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf")
' 2. Convert HTML File to PDF
Dim htmlFilePath = "path_to_your_html_file.html" ' Specify the path to your HTML file
Dim pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath)
pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf")
' 3. Convert URL to PDF
Dim url = "http://ironpdf.com" ' Specify the URL
Dim pdfFromUrl = renderer.RenderUrlAsPdf(url)
pdfFromUrl.SaveAs("URLToPDF.pdf")
End Sub
End Class
Kurulum
IronPDF, NuGet paket yöneticisi for IronPDF konsolu kullanılarak ya da Visual Studio paket yöneticisi kullanılarak kurulabilir.
dotnet add package IronPdf // Or Install-Package IronPdf

using System;
using IronPdf;
class Program
{
static void Main()
{
Console.WriteLine("Generating PDF using IronPDF.");
var displayFirstName = "<p>First Name is Joe</p>".AsSpan();
var displayLastName = "<p>Last Name is Doe</p>".AsSpan();
var displayAddress = "<p>12th Main, 7Th Cross, New York</p>".AsSpan();
var start = "<html><body>".AsSpan();
var end = "</body></html>".AsSpan();
var content = string.Concat(start.ToString(), displayFirstName.ToString(), displayLastName.ToString(), displayAddress.ToString(), end.ToString());
var pdfDocument = new ChromePdfRenderer();
pdfDocument.RenderHtmlAsPdf(content).SaveAs("span.pdf");
}
}
using System;
using IronPdf;
class Program
{
static void Main()
{
Console.WriteLine("Generating PDF using IronPDF.");
var displayFirstName = "<p>First Name is Joe</p>".AsSpan();
var displayLastName = "<p>Last Name is Doe</p>".AsSpan();
var displayAddress = "<p>12th Main, 7Th Cross, New York</p>".AsSpan();
var start = "<html><body>".AsSpan();
var end = "</body></html>".AsSpan();
var content = string.Concat(start.ToString(), displayFirstName.ToString(), displayLastName.ToString(), displayAddress.ToString(), end.ToString());
var pdfDocument = new ChromePdfRenderer();
pdfDocument.RenderHtmlAsPdf(content).SaveAs("span.pdf");
}
}
Imports System
Imports IronPdf
Friend Class Program
Shared Sub Main()
Console.WriteLine("Generating PDF using IronPDF.")
Dim displayFirstName = "<p>First Name is Joe</p>".AsSpan()
Dim displayLastName = "<p>Last Name is Doe</p>".AsSpan()
Dim displayAddress = "<p>12th Main, 7Th Cross, New York</p>".AsSpan()
Dim start = "<html><body>".AsSpan()
Dim [end] = "</body></html>".AsSpan()
Dim content = String.Concat(start.ToString(), displayFirstName.ToString(), displayLastName.ToString(), displayAddress.ToString(), [end].ToString())
Dim pdfDocument = New ChromePdfRenderer()
pdfDocument.RenderHtmlAsPdf(content).SaveAs("span.pdf")
End Sub
End Class
Bu örnekte, bir PDF belgesi oluşturmak için Span ile birlikte IronPDF kullanıyoruz.
Çıktı:

Oluşturulan PDF:

Lisanslama (Ücretsiz Deneme Mevcuttur)
IronPDF lisans bilgisi. Bu anahtar appsettings.json dosyasına yerleştirilmelidir.
"IronPdf.LicenseKey": "your license key"
Deneme lisansı almak için e-posta adresinizi sağlayın.
Sonuç
C#'ta Span, bellekle çalışmak için güçlü ve verimli bir yol sunar, performans ve esneklik açısından avantajlar sağlar. Sahip olmadıkları, bitişik yapısı, bellek tahsislerini ve kopyalamayı en aza indirmek gereken senaryolar için onu özellikle uygun kılar. Span'i kullanarak, geliştiriciler dizi manipülasyonundan yüksek performanslı sayısal işlemeye kadar çeşitli uygulamalarda daha iyi performans elde edebilirler. Özelliklerini anlayarak ve sınırlamalarını göz önünde bulundurarak, geliştiriciler çeşitli bellek manipülasyon görevlerinde Span'yi güvenli ve verimli bir şekilde kullanabilirler. IronPDF kütüphanesi genel bakış ile birlikte, beklemeksizin ve sonuç sınırları olmadan harika PDF belgeleri oluşturmak için kullanılabilir.
Lütfen IronPDF'nin Hızlı Başlangıç Kılavuzu Sayfası sayfasını ziyaret edin.
Sıkça Sorulan Sorular
C# içinde Span nedir ve neden önemlidir?
Span, C# 7.2'de tanıtılan ve kesintisiz bir bellek bölgesini temsil eden bir türdür. Önemlidir çünkü geliştiricilerin yığın tahsislerinin genel yükü olmadan düşük seviyeli bellek işlemlerini verimli bir şekilde gerçekleştirmesine olanak tanır, C#'ın güvenliğini ve performansını korur.
C# içinde Span, bellek manipülasyonunu nasıl optimize eder?
Span, bellek üzerinde sıfır kopya soyutlaması sağlayarak bellek manipülasyonunu optimize eder, veriyi çoğaltmadan mevcut bellek bloklarına referans vermeye olanak tanır. Bu, özellikle büyük veri hacimlerini işleyen uygulamalarda performans iyileştirmelerine yol açar.
Span ile ReadOnlySpan arasındaki fark nedir?
Span, belleğin değiştirilebilir bir görünümünü sağlayarak modifikasyonlara izin verirken, ReadOnlySpan, yalnızca okunabilir bir görünüm sağlar. Veri değiştirilmemesi gerektiğinde ReadOnlySpan kullanılır ve veri bütünlüğünü sağlarken benzer performans avantajları sunar.
C# içinde Span, yönetilmeyen bellekle kullanılabilir mi?
Evet, Span, yönetilmeyen belleğe bir işaretçiden bir span oluşturarak kullanılabilir. Bu, bellek uygun bir şekilde tahsis edilip serbest bırakılırken belleğin doğrudan manipüle edilmesine olanak tanır, örneğin Marshal.AllocHGlobal ve Marshal.FreeHGlobal gibi yöntemler kullanılarak.
IronPDF, PDF oluşturma için Span ile nasıl entegre olur?
IronPDF, belleği verimli bir şekilde yöneterek ve gereksiz tahsisatlardan kaçınarak Span ile birlikte dinamik bir şekilde PDF oluşturabilir. Bu entegrasyon, web içeriğinden PDF belgeleri oluşturmada geliştiricilere daha iyi performans sağlar.
Span kullanmanın bellek yönetimi açısından sınırlamaları nelerdir?
Span kullanmanın sınırlamaları arasında kesintisiz bellek gereksinimi, otomatik bellek yönetimi ve çöp toplayıcısının olmaması yer alır. Geliştiriciler, belleğin geçerliliğini ve sınırlarını manuel olarak sağlamalıdır.
C# içinde PDF işlemeyi nasıl yükleyebilirim?
IronPDF, C# projesine NuGet paket yöneticisi kullanılarak yüklenebilir. Projenize eklemek için dotnet add package IronPdf veya Install-Package IronPdf gibi komutlar kullanın.
Span kullanmanın dizgi manipülasyonu için avantajları nelerdir?
Span, bellek tahsisatlarını ve kopyalamayı minimize ederek verimli dizgi manipülasyonuna olanak tanır. Bu, büyük miktarda dizgi verisinin işlendiği performans açısından kritik kodlarda özellikle faydalıdır.
IronPDF için deneme sürümü mevcut mu?
Evet, IronPDF, e-posta adresinizi sağlayarak temin edebileceğiniz bir deneme lisansı sunar. Deneme lisans anahtarını kütüphaneyi kullanmak için appsettings.json dosyasına yerleştirin.
Span, asenkron metot çağrılarında kullanılabilir mi?
Evet, Span, verileri gereksiz kopyalamadan verimli bir şekilde işlemek için asenkron metot çağrılarında kullanılabilir. Bu, özellikle Memory veya Span kullanan I/O işlemleri ve dosya işleme için faydalıdır.




