Erstellen Sie eine PDF-Datei mit effizienter Speicherverwaltung. Sehen Sie sich die Ergebnisse in Aktion an!
using IronPdf;
using System;
var data = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
var span = new Span<int>(data, 2, 5); // Create a Span that includes elements from index 2 to 6
// Convert the span to a string for HTML content
string spanContent = string.Join(", ", span.ToArray());
// Create HTML content with the span data
string htmlContent = $"<h1>Span Data PDF</h1><p>The data in the span is: {spanContent}</p>";
// Initialize ChromePdfRenderer
var renderer = new ChromePdfRenderer();
// Render the HTML content as PDF
var pdfDocument = renderer.RenderHtmlAsPdf(htmlContent);
// Save the PDF file
string fileName = "SpanData.pdf";
pdfDocument.SaveAs(fileName);
Console.WriteLine($"PDF saved as: {fileName}");
*Span ist ein Typ, der in C# 7.2 als Teil der Spanstruktur im Namespace System. Er ist so konzipiert, dass er einen zusammenhängenden Bereich eines beliebigen Speichers darstellt. Im Gegensatz zu Arrays oder Sammlungen, wie z. B. Managed Heap, ist Span nicht Eigentümer des Stapelspeichers oder des Speicherbereichs, auf den er zeigt; stattdessen bietet es eine leichtgewichtige Sicht auf vorhandene Speicherblöcke. Diese Eigenschaft macht Span besonders leistungsfähig für Szenarien, in denen Sie effizient mit Speicherpuffern arbeiten müssen, ohne zusätzlichen Overhead und unsichere Codeszenarien zu verursachen. Später in diesem Artikel werden wir auch die Einführung in dieIronPDF-Bibliothek vonIron Software.
Hauptmerkmale der Spanne
1. Speicherverwaltung
Span in C# ermöglicht es Entwicklern, direkt mit Speicher zu arbeiten, ohne auf traditionelle Heap-Zuweisungen zurückgreifen zu müssen. Es bietet eine Möglichkeit, Speicherabschnitte aus bestehenden Arrays oder anderen Speicherquellen zu erstellen, wodurch zusätzliche Speicherkopien überflüssig werden.
2. Null-Kopie-Abstraktionen
Eines der herausragenden Merkmale von C# Span sind seine Null-Kopie-Abstraktionen. Anstatt Daten zu duplizieren, bietet Span eine Möglichkeit, effizient auf vorhandenen Speicher zu verweisen. Dies ist besonders vorteilhaft für Szenarien, in denen das Kopieren großer Datenmengen unpraktisch oder zu kostspielig wäre.
3. Zeiger-ähnliche Operationen
Während C# traditionell eine sichere High-Level-Sprache ist, führt Span ein gewisses Maß an Low-Level-Speichermanipulation ein, das der Arbeit mit Zeigern in Sprachen wie C oder C++ ähnelt. Entwickler können zeigerähnliche Operationen durchführen, ohne auf die Sicherheit und den verwalteten Charakter von C# zu verzichten.
4. Unveränderliche Natur
Trotz seiner Möglichkeiten für den Speicherzugriff auf niedriger Ebene bleibt C# Span unveränderlich. Das bedeutet, dass es zwar die Manipulation des Speichers erlaubt, aber gleichzeitig die Sicherheit erhöht, indem es unbeabsichtigte Änderungen verhindert.
Beispiel
using System;
class Program
{
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
{
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
Private 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
$vbLabelText $csharpLabel
ReadOnlySpan
Während Spanveränderlich ist und Änderungen an den zugrunde liegenden Daten zulässt, ist ReadOnlySpanist eine unveränderliche Ansicht des Speichers. Sie bietet eine Nur-Lese-Schnittstelle zu einem zusammenhängenden Speicherbereich und eignet sich daher für Szenarien, in denen Sie die Daten nur lesen, aber nicht verändern müssen.
Hier sind einige wichtige Punkte.
1. Schreibgeschützte Ansicht
Wie der Name schon sagt, ist ReadOnlySpanermöglicht es Ihnen, eine schreibgeschützte Ansicht eines Speicherblocks zu erstellen. Das bedeutet, dass Sie die Elemente nicht über eine ReadOnlySpan.
2. Darstellung des Speichers
Wie Span, ReadOnlySpanist nicht Eigentümer des Speichers, auf den es zeigt. Er bezieht sich auf vorhandenen Speicher und kann auf Arrays, Stack-allocated Memory oder Native Memory verweisen.
3. Leistungsvorteile
Wie Span, ReadOnlySpankann im Vergleich zu herkömmlichen Erfassungsarten eine bessere Leistung bieten, insbesondere bei großen Datenmengen, da weniger Kopiervorgänge erforderlich sind.
4. Prüfung ohne Grenzen
Wie bei Span, ReadOnlySpanführt keine Überprüfung der Grenzen durch. Es liegt in der Verantwortung des Entwicklers, sicherzustellen, dass die Operationen innerhalb der Grenzen des zugrunde liegenden Speichers bleiben.
5. Verwendung mit Array Slicing
ReadOnlySpanunterstützt das Slicing, d. h. Sie können Teilbereiche erstellen, die auf einen Teil des ursprünglichen Speichers verweisen.
Beispiel
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
$vbLabelText $csharpLabel
Es gibt viele verschiedene Möglichkeiten, ReadOnlySpan zu erstellen und mit ihm zu arbeiten. Nachstehend einige Beispiele.
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
Dim substringSpan As ReadOnlySpan(Of Char) = spanFromString.Slice(startIndex, length)
$vbLabelText $csharpLabel
3. Übergabe von Substraten an eine Methode
Pass ReadOnlySpanals Parameter für die Methode.
void ProcessSubstringfromReadOnlySpan(ReadOnlySpan<char> substring)
{
// Perform operations on the substring
}
// Usage
ProcessSubstringfromReadOnlySpan(spanFromString.Slice(startIndex, length));
void ProcessSubstringfromReadOnlySpan(ReadOnlySpan<char> substring)
{
// Perform operations on the substring
}
// Usage
ProcessSubstringfromReadOnlySpan(spanFromString.Slice(startIndex, length));
Private Sub ProcessSubstringfromReadOnlySpan(ByVal substring As ReadOnlySpan(Of Char))
' Perform operations on the substring
End Sub
' Usage
ProcessSubstringfromReadOnlySpan(spanFromString.Slice(startIndex, length))
$vbLabelText $csharpLabel
4. Suche innerhalb einer Zeichenkette
ReadOnlySpanfür die Suche innerhalb einer Zeichenkette mit IndexOf().
int index = stringSpan.IndexOf('W');
int index = stringSpan.IndexOf('W');
Dim index As Integer = stringSpan.IndexOf("W"c)
$vbLabelText $csharpLabel
5. Verwendung von Memory-Mapped-Dateien
ReadOnlySpankann mit Memory-Mapped-Dateien effizienter sein.
using (var memmf = MemoryMappedFile.CreateFromFile("data.bin"))
{
using (var accessor = memmf.CreateViewAccessor())
{
ReadOnlySpan<byte> dataSpan;
accessor.Read(0, out dataSpan);
// Process data directly from the memory-mapped file
ProcessData(dataSpan);
}
}
using (var memmf = MemoryMappedFile.CreateFromFile("data.bin"))
{
using (var accessor = memmf.CreateViewAccessor())
{
ReadOnlySpan<byte> dataSpan;
accessor.Read(0, out dataSpan);
// Process data directly from the memory-mapped file
ProcessData(dataSpan);
}
}
Using memmf = MemoryMappedFile.CreateFromFile("data.bin")
Using accessor = memmf.CreateViewAccessor()
Dim dataSpan As ReadOnlySpan(Of Byte) = Nothing
accessor.Read(0, dataSpan)
' Process data directly from the memory-mapped file
ProcessData(dataSpan)
End Using
End Using
$vbLabelText $csharpLabel
6. Effiziente Manipulation von Zeichenketten
ReadOnlySpankann für die effiziente Manipulation von Zeichenketten verwendet werden.
// Replace a character in a substring without creating a new string
spanFromString.Slice(startIndex, length).CopyTo(newSpan);
// Replace a character in a substring without creating a new string
spanFromString.Slice(startIndex, length).CopyTo(newSpan);
' Replace a character in a substring without creating a new string
spanFromString.Slice(startIndex, length).CopyTo(newSpan)
$vbLabelText $csharpLabel
7. Übergabe von Substraten an APIs
Bei der Arbeit mit externen Bibliotheken oder APIs, die mit Zeichenabständen arbeiten.
void ExternalApiMethod(ReadOnlySpan<char> data)
{
// Call the external API with the character span
}
// Usage
ExternalApiMethod(spanFromString.Slice(startIndex, length));
void ExternalApiMethod(ReadOnlySpan<char> data)
{
// Call the external API with the character span
}
// Usage
ExternalApiMethod(spanFromString.Slice(startIndex, length));
Private Sub ExternalApiMethod(ByVal data As ReadOnlySpan(Of Char))
' Call the external API with the character span
End Sub
' Usage
ExternalApiMethod(spanFromString.Slice(startIndex, length))
$vbLabelText $csharpLabel
ReadOnlySpanbietet eine Möglichkeit, effizienter mit Zeichenketten zu arbeiten, insbesondere in Szenarien, in denen Speicherzuweisungen und Kopieren minimiert werden sollen. Es ist ein leistungsfähiges Werkzeug zur Optimierung von leistungskritischem Code und kann besonders bei großen Mengen an Zeichenkettendaten von Vorteil sein.
Spannenbegrenzungen
Obwohl Span in C# eine leistungsstarke Funktion mit zahlreichen Vorteilen ist, gibt es auch einige Einschränkungen und Überlegungen, insbesondere im Zusammenhang mit zusammenhängendem und nicht zusammenhängendem Speicher. Lassen Sie uns diese Einschränkungen untersuchen:
1. Zusammenhängende Speicherpuffer
1.1 Keine automatische Speicherverwaltung
Spannweiteverwaltet den Speicher, auf den es zeigt, nicht. Das bedeutet, dass, wenn der zugrunde liegende verwaltete Speicher freigegeben wird oder aus dem Anwendungsbereich verschwindet, die Verwendung des Spanführt zu undefiniertem Verhalten oder möglichen Abstürzen. Die Entwickler müssen sicherstellen, dass der zugrundeliegende Speicher noch gültig ist, wenn sie eine Span.
1.2 Keine Müllabfuhr
Da Spankeinen Speicher besitzt, unterliegt er nicht der Garbage Collection. Daher müssen Sie vorsichtig sein, wenn Sie mit Stack-zugeordnetem Speicher oder Speicher arbeiten, der eine kürzere Lebensdauer hat als der Spanselbst.
1.3 Bounds Checking ist deaktiviert
Spannweiteund ReadOnlySpannweiteführen standardmäßig keine Überprüfung der Grenzen durch. Dies kann dazu führen, dass auf ungültige Speicherplätze zugegriffen wird, wenn nicht sorgfältig damit umgegangen wird. Die Entwickler müssen manuell sicherstellen, dass die Operationen auf einem Spaninnerhalb der Grenzen des zugrunde liegenden Speichers bleiben.
1.4 Keine Unterstützung für nicht zusammenhängenden Speicher
Spannweiteist für die Arbeit mit zusammenhängendem Speicher ausgelegt. Wenn Sie nicht zusammenhängenden Speicher haben oder komplexere Datenstrukturen darstellen müssen, können Sie Spanist möglicherweise nicht die beste Wahl.
1.5 Es werden nicht alle Operationen unterstützt
Während Spanunterstützt viele gängige Operationen wie Slicing, Indexierung und Iteration, aber nicht alle Operationen werden unterstützt. Sie können zum Beispiel die Größe einer Spanne nicht ändernund bestimmte Operationen, bei denen die Länge des zugrunde liegenden Speichers verändert wird, sind nicht zulässig.
1.6 Eingeschränkte Plattformkompatibilität
Während Spanteil des .NET Standards und .NET Core ist, ist es möglicherweise nicht auf allen Plattformen oder Umgebungen verfügbar. Es ist von entscheidender Bedeutung, dass Ihre Zielplattform die Spanwenn Sie es in Ihrem Code verwenden wollen.
2. Nicht zusammenhängende Speicherpuffer
2.1 Eingeschränkte Unterstützung für nicht zusammenhängenden Speicher
ReadOnlySpanist in erster Linie darauf ausgelegt, nahtlos mit zusammenhängenden Speicherblöcken oder Puffern zu arbeiten. Es ist möglicherweise nicht die beste Wahl für Szenarien, in denen nicht zusammenhängende Speicherpuffer oder Strukturen mit Lücken im Speicher betroffen sind.
2.2 Strukturelle Beschränkungen
Bestimmte Datenstrukturen oder Szenarien, die auf nicht zusammenhängenden Speicher angewiesen sind, passen möglicherweise nicht gut zu ReadOnlySpan. So sind beispielsweise Datenstrukturen wie verknüpfte Listen oder Graphenstrukturen aufgrund der Anforderungen von ReadOnlySpan an den zusammenhängenden Speicher möglicherweise nicht gut geeignet.
2.3 Komplexe Zeigeroperationen
In Situationen, in denen es um nicht zusammenhängenden Speicher geht, insbesondere wenn komplizierte Zeigerarithmetik erforderlich ist, kann ReadOnlySpanbieten möglicherweise nicht die gleiche Kontrolle auf niedriger Ebene und Flexibilität wie rohe Zeiger in Sprachen wie C++. In solchen Fällen könnte die Verwendung von unsicherem Code mit Zeigern sinnvoller sein.
2.4 Fehlende direkte Unterstützung in einigen APIs
Ähnlich wie bei zusammenhängendem Speicher ist es wichtig zu beachten, dass nicht alle APIs oder Bibliotheken nicht zusammenhängenden Speicher direkt unterstützen, der durch ReadOnlySpan. Die Anpassung an solche Szenarien kann zusätzliche Zwischenschritte oder Konvertierungen erforderlich machen, um die Kompatibilität zu gewährleisten.
Span und nicht verwalteter Speicher
In C# kann Span effektiv mit nicht verwaltetem Speicher verwendet werden, um speicherbezogene Operationen auf kontrollierte und effiziente Weise durchzuführen. Unverwalteter Speicher bezieht sich auf Speicher, der nicht vom Garbage Collector der .NET-Laufzeitumgebung verwaltet wird, und beinhaltet oft die Verwendung von nativen Speicherzuweisungen und -freigaben. Hier ist, wie Span kann mit unmanaged Speicher in C# verwendet werden.
Zuweisung von nicht verwaltetem Speicher
Um nicht verwalteten Speicher zuzuweisen, können Sie die Klasse System.Runtime.InteropServices.MemoryMarshal verwenden. Die Methode Marshal.AllocHGlobal weist Speicher zu und gibt einen Zeiger auf den zugewiesenen Block zurück. Der zugewiesene Speicher oder die Speicheradresse wird in einem unmanagedMemory-Zeiger gehalten und hat Lese- und Schreibzugriff. Auf die zusammenhängenden Bereiche des Speichers kann leicht zugegriffen werden.
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
$vbLabelText $csharpLabel
Im obigen Quellcode weisen wir mit Marshal.AllocHGlobal einen Block nicht verwalteten Speichers zu und erstellen dann eine Spanunter Verwendung des Zeigers, der aus dem nicht verwalteten Speicher stammt. Dadurch können wir mit nicht verwaltetem Speicher arbeiten, indem wir die bekannte Span-API verwenden. Es ist wichtig zu wissen, dass Sie bei der Arbeit mit nicht verwaltetem Speicher für die Verwaltung der Zuweisung und Freigabe des Speichers verantwortlich sind.
Kopieren von Daten in und aus nicht verwaltetem Speicher
Span bietet Methoden wie Slice, CopyTo und ToArray, die für das effiziente Kopieren von Daten zwischen verwaltetem und nicht verwaltetem Speicher verwendet werden können.
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 = MemoryMarshal.Allocate<int>(sourceArray.Length);
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 = MemoryMarshal.Cast<int, byte>(destinationPointer, 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
MemoryMarshal.Free(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 = MemoryMarshal.Allocate<int>(sourceArray.Length);
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 = MemoryMarshal.Cast<int, byte>(destinationPointer, 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
MemoryMarshal.Free(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 = MemoryMarshal.Allocate(Of Integer)(sourceArray.Length)
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 Span(Of Integer) = MemoryMarshal.Cast(Of Integer, Byte)(destinationPointer, 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
MemoryMarshal.Free(destinationPointer)
End Try
End Sub
End Class
$vbLabelText $csharpLabel
In diesem Beispiel:
MemoryMarshal.Allocate(sourceArray.Length) weist nicht verwalteten Speicher für die Zieldaten zu. MemoryMarshal.Cast<int, byte>(destinationPointer, sourceArray.Length) erstellt eine Spanneaus dem zugewiesenen unverwalteten Speicher. Die Funktion sourceSpan.CopyTo(destinationSpan) methode kopiert die Daten aus dem verwalteten Array in den nicht verwalteten Speicher. Die Werte im Zielspeicher werden ausgedruckt, um den Kopiervorgang zu überprüfen. Das GedächtnisMarschall.Free(zielZeiger) methode wird verwendet, um den nicht verwalteten Speicher wieder freizugeben, wenn er fertig ist.
Unsicheren Code verwenden
Wenn Sie mit nicht verwaltetem Speicher arbeiten, können Sie auch unsicheren Code mit Zeigern verwenden. In solchen Fällen können Sie einen Zeiger aus dem Span erhalten, indem Sie die Funktion Unsafe.AsPointer() methode.
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 unsafe code to work with pointers
// ref t
unsafe
{
byte* pointer = (byte*)Unsafe.AsPointer(ref struct 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;
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
// ref t
unsafe
{
byte* pointer = (byte*)Unsafe.AsPointer(ref struct 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
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
' ref t
'INSTANT VB TODO TASK: C# 'unsafe' code is not converted by Instant VB:
' unsafe
' {
' byte* pointer = (byte*)Unsafe.AsPointer(ref struct 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
$vbLabelText $csharpLabel
In diesem Beispiel verwenden wir die Methode Unsafe.AsPointer, um einen Zeiger von Span zu erhalten. Dies ermöglicht uns die Verwendung von unsicherem Code, wenn wir direkt mit Zeigern arbeiten.
Denken Sie daran, dass es bei der Arbeit mit nicht verwaltetem Speicher wichtig ist, die Zuweisung und Freigabe richtig zu verwalten, um Speicherlecks zu vermeiden. Geben Sie nicht verwalteten Speicher immer mit geeigneten Methoden frei, z. B. mit Marshal.FreeHGlobal(). Seien Sie außerdem vorsichtig bei der Verwendung von unsicherem Code, da dieser bei unsachgemäßer Handhabung potenzielle Sicherheitsrisiken bergen kann.
Span und asynchrone Methodenaufrufe
Die Verwendung von Span in Verbindung mit asynchronen Methodenaufrufen in C# ist eine leistungsstarke Kombination, vor allem wenn es um große Datenmengen oder E/A-Operationen geht. Ziel ist es, asynchrone Operationen ohne unnötiges Kopieren von Daten effizient abzuwickeln. Lassen Sie uns untersuchen, wie Sie Span in asynchronen Szenarien nutzen können:
1. Asynchrone E/A-Operationen:
Bei asynchronen E/A-Operationen, wie dem Lesen oder Schreiben von Daten in einen Stream, können Sie Memoryoder Spannweiteum effizient mit den Daten zu arbeiten, ohne zusätzliche Puffer zu erzeugen.
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));
}
}
void ProcessData(Span<byte> data)
{
// Perform operations on the data
}
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));
}
}
void ProcessData(Span<byte> data)
{
// Perform operations on the data
}
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 Sub ProcessData(ByVal data As Span(Of Byte))
' Perform operations on the data
End Sub
$vbLabelText $csharpLabel
In diesem Beispiel liest die Methode ReadAsync asynchron Daten aus einem Stream in den Puffer. Die ProcessData-Methode verarbeitet dann die Daten direkt aus dem Spanohne sie in einen anderen Puffer zu kopieren.
2. Asynchrone Dateioperationen:
Ähnlich wie bei E/A-Operationen können Sie bei asynchronen Dateioperationen Span verwenden, um Daten ohne zusätzliches Kopieren effizient zu verarbeiten.
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));
}
}
}
void ProcessData(Span<byte> data)
{
// Perform operations on the data
}
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));
}
}
}
void ProcessData(Span<byte> data)
{
// Perform operations on the data
}
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 Sub ProcessData(ByVal data As Span(Of Byte))
' Perform operations on the data
End Sub
$vbLabelText $csharpLabel
Hier liest die ReadAsync-Methode Daten aus einem Dateistrom in den Puffer, und die ProcessData-Methode verarbeitet die Daten direkt aus dem Span.
3. Asynchrone Aufgabenverarbeitung:
Wenn Sie mit asynchronen Aufgaben arbeiten, die Daten produzieren oder verbrauchen, können Sie Memoryoder Spannweiteum unnötiges Kopieren zu vermeiden.
async Task<int> ProcessDataAsync(int[] data)
{
// Asynchronous processing of data
await Task.Delay(1000);
// Returning the length of the processed data
return data.Length;
}
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}");
}
async Task<int> ProcessDataAsync(int[] data)
{
// Asynchronous processing of data
await Task.Delay(1000);
// Returning the length of the processed data
return data.Length;
}
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}");
}
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
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
$vbLabelText $csharpLabel
In diesem Beispiel verarbeitet die Methode ProcessDataAsync die Daten asynchron und gibt die Länge der verarbeiteten Daten zurück, ohne dass zusätzliche Kopien erforderlich sind.
Einführung in IronPDF
Überblick über die IronPDF-Bibliothek ist die neueste C# PDF-Bibliothek vonIron Software mit dem sich schöne PDF-Dokumente dynamisch mit C#-Code erzeugen lassen. IronPDF bietet eine Vielzahl von Funktionen, wie z. B. PDF-Erzeugung aus HTML, Konvertierung von HTML-Inhalten in PDF, Zusammenführen oder Teilen von PDF-Dateien usw.
Das Hauptmerkmal von IronPDF ist seineHTML-zu-PDF-Funktionalitätdie Layouts und Stile beibehält. Es kann PDFs aus Webinhalten generieren und eignet sich daher hervorragend für Berichte, Rechnungen und Dokumentationen. Dieses Tool unterstützt die Umwandlung von HTML-Dateien, URLs und HTML-Strings in PDF-Dateien.
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
dotnet add package IronPdf
// Or
Install-Package IronPdf
dotnet add package IronPdf
// Or
Install-Package IronPdf
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'dotnet add package IronPdf Install-Package IronPdf
$vbLabelText $csharpLabel
using System;
class Program
{
static void Main()
{
Console.WriteLine("Generating PDF using IronPDF.");
var displayFirstName = "<p>First Name is Joe</p>".AsSpan();
var displayLastName = "<p>First Name is Doe</p>".AsSpan();
var displayAddress = "<p>12th Main, 7Th Cross, New York</p>".AsSpan();
var start = @"<!DOCTYPE html>
<html>
<body>".AsSpan();
var end = @"<!DOCTYPE html>
<html>
<body>";
var content = string.Concat(start, displayFirstName, displayLastName, string.Concat(displayAddress, end));
var pdfDocument = new ChromePdfRenderer();
pdfDocument.RenderHtmlAsPdf(content).SaveAs("span.pdf");
}
}
using System;
class Program
{
static void Main()
{
Console.WriteLine("Generating PDF using IronPDF.");
var displayFirstName = "<p>First Name is Joe</p>".AsSpan();
var displayLastName = "<p>First Name is Doe</p>".AsSpan();
var displayAddress = "<p>12th Main, 7Th Cross, New York</p>".AsSpan();
var start = @"<!DOCTYPE html>
<html>
<body>".AsSpan();
var end = @"<!DOCTYPE html>
<html>
<body>";
var content = string.Concat(start, displayFirstName, displayLastName, string.Concat(displayAddress, end));
var pdfDocument = new ChromePdfRenderer();
pdfDocument.RenderHtmlAsPdf(content).SaveAs("span.pdf");
}
}
Imports System
Friend Class Program
Shared Sub Main()
Console.WriteLine("Generating PDF using IronPDF.")
Dim displayFirstName = "<p>First Name is Joe</p>".AsSpan()
Dim displayLastName = "<p>First Name is Doe</p>".AsSpan()
Dim displayAddress = "<p>12th Main, 7Th Cross, New York</p>".AsSpan()
Dim start = "<!DOCTYPE html>
<html>
<body>".AsSpan()
Dim [end] = "<!DOCTYPE html>
<html>
<body>"
Dim content = String.Concat(start, displayFirstName, displayLastName, String.Concat(displayAddress, [end]))
Dim pdfDocument = New ChromePdfRenderer()
pdfDocument.RenderHtmlAsPdf(content).SaveAs("span.pdf")
End Sub
End Class
$vbLabelText $csharpLabel
In diesem Beispiel verwenden wir Span zusammen mit IronPDF, um ein PDF-Dokument zu erzeugen.
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'"IronPdf.LicenseKey": "your license key"
$vbLabelText $csharpLabel
Geben Sie Ihre E-Mail-Adresse an, um eine Testlizenz zu erhalten.
Schlussfolgerung
Spannweitein C# bietet eine leistungsstarke und effiziente Möglichkeit, mit dem Speicher zu arbeiten, und bietet Vorteile in Bezug auf Leistung und Flexibilität. Die nicht-besitzende, zusammenhängende Natur macht es besonders geeignet für Szenarien, in denen die Minimierung von Speicherzuweisungen und -kopien entscheidend ist. Durch den Einsatz von Span können Entwickler eine bessere Leistung in einer Vielzahl von Anwendungen erzielen, die von der Zeichenkettenmanipulation bis zur leistungsstarken numerischen Verarbeitung reichen. Wenn Entwickler die Funktionen verstehen und ihre Grenzen berücksichtigen, können sie die Spanfür verschiedene Speichermanipulationsaufgaben sicher und effizient. Zusammen mitÜberblick über die IronPDF-Bibliothekkann es verwendet werden, um großartige PDF-Dokumente zu erzeugen, ohne Grenzen zu erwarten und zu erreichen.
Chipego hat eine natürliche Fähigkeit zum Zuhören, die ihm hilft, Kundenprobleme zu verstehen und intelligente Lösungen anzubieten. Er trat dem Iron Software-Team 2023 bei, nachdem er einen Bachelor of Science in Informationstechnologie erworben hatte. IronPDF und IronOCR sind die beiden Produkte, auf die sich Chipego konzentriert hat, aber sein Wissen über alle Produkte wächst täglich, da er neue Wege findet, Kunden zu unterstützen. Er genießt die Zusammenarbeit bei Iron Software, da Teammitglieder aus dem gesamten Unternehmen ihre unterschiedlichen Erfahrungen einbringen und so zu effektiven, innovativen Lösungen beitragen. Wenn Chipego nicht an seinem Schreibtisch sitzt, kann man ihn oft bei einem guten Buch oder beim Fußballspielen antreffen.
< PREVIOUS C# IDE (Wie es für Entwickler funktioniert)
NÄCHSTES > Opentelemetry C# (Wie es für Entwickler funktioniert)