C# Span(開發者如何理解其工作原理)
Span 是 C# 7.2 中引入的一種類型,是 System 命名空間中 Span
Span 的主要特性
1.記憶體管理
C# 中的 Span 可讓開發人員直接使用記憶體,而無需借助傳統的堆分配。 它提供了從現有陣列或其他記憶體來源建立記憶體切片的方法,省去了額外的記憶體副本。
2.零複製抽象
C# Span 的突出特點之一是其零複製抽象。 Span 提供了一種有效引用現有記憶體的方式,而非重複資料。 這對複製大量資料不切實際或成本過高的情況特別有利。
3.類似指標的操作
雖然 C# 傳統上是一種高階、安全的語言,但 Span 引入了一定程度的低階記憶體操作,類似於在 C 或 C++ 等語言中使用指針。 開發人員可以在不犧牲 C# 的安全性和管理性的前提下,執行類指針的操作。
4.永恆不變的本質
儘管 C# Span 具備低階記憶體存取的能力,但它仍然是不可變的。 這意味著,在允許操作記憶體的同時,還要透過防止意外修改來強制執行安全性。
範例
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);
}
}
}ReadOnlySpan
Span
以下是一些重點。
1.唯讀檢視
顧名思義,ReadOnlySpan
2.記憶體表示法
如同 Span
3.效能優點
就像 Span
4.無界限檢查
如同 Span
5.使用陣列切片。
ReadOnlySpan
範例
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;
}
}有許多不同的方法可以建立 ReadOnlySpan 並使用它。 以下是一些範例。
1.從字串建立 ReadOnlySpan。
string msg = "Hello, World!";
ReadOnlySpan<char> span1 = msg.AsSpan();
// Read-only manipulation
char firstChar = span1[0];
Console.WriteLine(firstChar); // Outputs: Hstring msg = "Hello, World!";
ReadOnlySpan<char> span1 = msg.AsSpan();
// Read-only manipulation
char firstChar = span1[0];
Console.WriteLine(firstChar); // Outputs: H2.使用子串工作
在 ReadOnlySpanSlice
// 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'3.將子串傳送至方法。
傳送 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));4.在字串內搜尋
ReadOnlySpanIndexOf() 在字串內搜尋。
ReadOnlySpan<char> stringSpan = "Hello, World!".AsSpan();
int index = stringSpan.IndexOf('W');
Console.WriteLine(index); // Outputs: 7ReadOnlySpan<char> stringSpan = "Hello, World!".AsSpan();
int index = stringSpan.IndexOf('W');
Console.WriteLine(index); // Outputs: 75.使用記憶體映射檔案。
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);
}
}
}
}6.高效的字串操作
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: StringSpan<char> newSpan = new char[6];
ReadOnlySpan<char> spanFromString = "Sample String".AsSpan().Slice(7, 6);
spanFromString.CopyTo(newSpan);
Console.WriteLine(new string(newSpan)); // Outputs: String7.將子串傳送至 API。
當使用外部函式庫或 API 運作字元跨度時。
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));ReadOnlySpan
跨度限制
C# 中的 Span 功能強大,優點眾多,但也有一定的限制和注意事項,尤其是在連續記憶體和非連續記憶體的情況下。 讓我們來探討這些限制:
1.連續記憶體緩衝區。
1.1 無自動記憶體管理。
Span
1.2 無垃圾回收。
由於 Span
1.3 邊界檢查已停用。
Span
1.4 不支援非連續記憶體。
Span
1.5 並非所有操作都支援。
雖然 Span
1.6有限的平台相容性
雖然 Span
2.非連續記憶體緩衝區
2.1 對非連續記憶體的有限支援
ReadOnlySpan
2.2結構限制
某些依賴於非連續記憶體的資料結構或情境可能與 ReadOnlySpan
2.3複雜指標操作
在涉及非連續記憶體的情況下,特別是那些需要複雜的指標運算的情況下,ReadOnlySpan
2.4 某些 API 缺乏直接支援。
與連續記憶體相似,需要注意的是,並非所有 API 或函式庫都可能直接支援以 ReadOnlySpan
跨和非管理記憶體
在 C# 中,Span 可以有效地與非管理記憶體搭配使用,以受控且有效率的方式執行與記憶體相關的作業。 非管理記憶體指的是未被 .NET runtime 的垃圾回收器管理的記憶體,它通常涉及使用本機記憶體分配和取消分配。 以下是 Span 如何利用 C# 中的非管理記憶體。
分配非管理記憶體
若要分配非管理記憶體,您可以使用 System.Runtime.InteropServices.MemoryMarshal 類別。 Marshal.AllocHGlobal 方法會分配記憶體,並傳回已分配區塊的指標。 分配的記憶體或記憶體位址會以非管理記憶體指針 (unmanagedMemory pointer) 的方式持有,並會具有讀寫存取權。 可輕鬆存取記憶體的連續區域。
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);
}
}在上述原始碼中,我們使用 Marshal.AllocHGlobal 分配一個非管理記憶體區塊,然後再使用從非管理記憶體取得的指標建立一個 Span<byte> 。 這可讓我們使用熟悉的 Span API 來處理非管理記憶體。 值得注意的是,在使用非管理記憶體時,您必須負責管理記憶體的分配和取消分配。
將資料複製到非管理記憶體或從非管理記憶體複製資料。
Span 提供了像 Slice, CopyTo 和 ToArray 之類的方法,可用於在受管理記憶體和非受管理記憶體之間有效地複製資料。
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);
}
}
}在這個範例中
Marshal.AllocHGlobal為目標資料分配非管理記憶體。new Span<int>(destinationPointer.ToPointer(),sourceArray.Length)從分配的非管理記憶體中建立一個Span<int>。sourceSpan.CopyTo(destinationSpan)方法會將資料從受管陣列複製到非受管記憶體。- 目的記憶體中的值會被列印出來,以驗證複製作業。
Marshal.FreeHGlobal(destinationPointer)方法用來在完成時取消指定非管理記憶體。
使用不安全的程式碼
在處理非管理記憶體時,也可能會使用指針的不安全程式碼。 在這種情況下,您可以使用 Unsafe.AsPointer() 方法從 Span 取得指針。
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);
}
}在這個範例中,我們使用 Unsafe.AsPointer 方法從 Span 取得指標。 這可讓我們在直接處理指標時使用不安全的程式碼。
請記住,在使用非管理記憶體時,妥善管理分配和取消分配以避免記憶體洩漏是非常重要的。 請務必使用適當的方法釋放非管理記憶體,例如 Marshal.FreeHGlobal() 。 此外,使用不安全的程式碼時要小心,因為如果處理不當,可能會帶來潛在的安全風險。
Span 和異步方法呼叫。
在 C# 中將 Span 與異步方法呼叫結合使用是一個強大的組合,尤其是在處理大量資料或 I/O 作業時。 目標是在沒有不必要複製資料的情況下,有效率地處理非同步作業。 讓我們來探討如何在異步情境中利用 Span:
1.異步 I/O 操作: 2.
在處理異步 I/O 作業 (例如讀取或寫入資料至串流) 時,您可以使用 Memory
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
}
}在這個範例中,ReadAsync 方法以異步方式將資料從串流讀取到緩衝區中。 之後,ProcessData 方法會直接處理 Span
2. 異步檔案作業: 3.
與 I/O 作業類似,在處理異步檔案作業時,您可以使用 Span 來有效率地處理資料,而無需額外複製。
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
}
}在這裡,ReadAsync 方法將資料從檔案串流讀入緩衝區,而 ProcessData 方法則直接從 Span
3. 異步任務處理: 4.
在處理產生或消耗資料的異步任務時,您可以使用 Memory
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}");
}
}在這個範例中,ProcessDataAsync 方法以異步方式處理資料,並返回已處理資料的長度,而不需要額外的副本。
介紹 IronPDF。
IronPDF 函式庫概述是 Iron Software 最新推出的 C# PDF 函式庫,可用於使用 C# 程式碼動態地即時產生精美的 PDF 文件。 IronPDF 提供多種功能,例如從 HTML 產生 PDF、將 HTML 內容轉換為 PDF、合併或分割 PDF 檔案等。
IronPdf 的主要功能是其HTML 轉 PDF 功能,可保留版面和樣式。 它可以從網頁內容產生 PDF,非常適合報告、發票和文件。 此工具支援將 HTML 檔案、URL 和 HTML 字串轉換為 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");
}
}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");
}
}安裝
IronPDF 可使用 NuGet package manager for IronPDF 控制台或 Visual Studio package manager 進行安裝。
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");
}
}在這個範例中,我們使用 Span 與 IronPDF 來產生 PDF 文件。
Output:
!a href="/static-assets/pdf/blog/csharp-span/csharp-span-2.webp">C# Span (How It Works For Developers):圖 2 - 控制台輸出
生成的 PDF:

授權(可免費試用)
IronPDF授權資訊。 此 key 需要放在 appsettings.json 中。
"IronPdf.LicenseKey": "your license key"提供您的電子郵件以取得試用授權。
結論
C# 中的 Span
請造訪 IronPDF"快速入門文件"頁面。
常見問題解答
Span是什麼在 C# 中使用它,以及為什麼它重要?
跨距是 C# 7.2 中引入的一種類型,它表示記憶體中的連續區域。它非常重要,因為它允許開發人員有效地執行底層記憶體操作,而無需進行堆分配,從而保持 C# 的安全性和效能。
Span是如何運作的如何在 C# 中優化記憶體操作?
跨距它透過提供零拷貝記憶體抽象來優化記憶體操作,使開發人員能夠在不複製資料的情況下引用現有記憶體區塊。這顯著提升了效能,尤其是在處理大量資料的應用程式中。
Span 和 Span 有什麼不同?和唯讀跨度?
跨距是記憶體的可變視圖,允許進行修改,而 ReadOnlySpan 則不然。提供唯讀視圖。 ReadOnlySpan當資料不應被修改時,可以使用此方法,在提供類似效能優勢的同時,確保資料完整性。
罐跨距可以在 C# 中使用非託管記憶體嗎?
是的,Span可以透過從指向非託管記憶體的指標建立跨度來使用非託管記憶體。這允許直接操作內存,同時確保使用諸如Marshal.AllocHGlobal和Marshal.FreeHGlobal之類的方法正確地分配和釋放內存。
IronPDF 如何與 Span 集成用於生成PDF文件?
IronPDF 可以與 Span 協同工作。透過有效率地管理記憶體並避免不必要的記憶體分配,實現動態產生 PDF 檔案。此整合使開發人員能夠以更高的效能從 Web 內容建立 PDF 文件。
使用 Span 有哪些局限性用於記憶體管理?
使用 Span 的局限性其中包括對連續記憶體的要求、缺乏自動記憶體管理和垃圾回收機制,以及不支援非連續記憶體。開發人員必須手動確保記憶體的有效性和邊界。
如何在C#中安裝IronPDF以進行PDF處理?
可以使用 NuGet 套件管理器將 IronPDF 安裝到 C# 專案中。使用諸如dotnet add package IronPdf或Install-Package IronPdf之類的命令將其新增至您的專案。
使用 Span 有什麼好處?用於字串操作?
跨距它透過最大限度地減少記憶體分配和複製操作,實現了高效的字串操作。這對於需要處理大量字串資料的效能關鍵型程式碼尤其有利。
IronPDF有試用版嗎?
是的,IronPDF 提供試用許可證,您可以透過提供電子郵件地址來取得。試用許可證金鑰需要加入到appsettings.json檔案中才能使用該庫。
罐跨距能否用於異步方法呼叫?
是的,Span可用於非同步方法調用,以有效率地處理數據,避免不必要的複製。這在 I/O 操作和檔案處理中尤其有用,可以充分利用Memory或Span 。







