“Ham” dosya sistemi erişimlerinden sonra, bunlar artık .NET 6’da doğrudan bellek erişimleridir.
Doğrudan bellek erişimi için .NET 6’da yeni bir sınıf var System.Runtime.InteropServices.NativeMemory ve sürüm 1.0’dan beri C#’ta bulunan işaretçi aritmetiği ile bağlantı. Bu dersi sadece bir derste yapabilirsiniz. unsafe-Bloğu kullan.
Aşağıdaki liste, doğrudan bellek erişiminin dikkate değer örneklerini göstermektedir:
Bu saçmalığı inşa etmezsen, sonunda kabul etmek zorunda kalırsın. NativeMemory.Free() ayrılmış belleği serbest bırakın.
static public void DirectMemoryAllocation()
{
unsafe
{
nuint MemSize = 1024 * 100;
for (int i = 0; i < 1; i++)
{
// Hole Speicher "ausgenullt" (alternativ: Alloc())
Console.WriteLine($"Allokiere nun {MemSize} Bytes...");
byte* m1 = (byte*)System.Runtime.InteropServices.
NativeMemory.AllocZeroed(MemSize);
CUI.H2("Wert Lesen und ändern");
IntPtr p1 = (IntPtr)m1;
Console.WriteLine("Speicheradresse: " + p1);
Console.WriteLine("Inhalt vorher: " + *m1);
Debug.Assert(*m1 == 0);
*m1 = 42;
Console.WriteLine("Inhalt nachher: " + *m1);
Debug.Assert(*m1 == 42);
CUI.H2("Schaue etwas weiter in den " +
"allokierten Speicher");
IntPtr p2 = new IntPtr(p1.ToInt64() + 10);
byte w2 = *(byte*)p2.ToPointer();
Console.WriteLine("Speicheradresse: " + p2 +
" Wert: " + w2);
Debug.Assert(w2 == 0);
byte* m2 = (byte*)p2.ToPointer();
Console.WriteLine("Inhalt vorher: " + *m2);
*m2 = 42;
Console.WriteLine("Inhalt nachher: " + *m2);
Debug.Assert(*m2 == 42);
try
{
// bei dem folgenden Unsinn des Entwicklers
// hilft in .NET Core CLR kein try-catch!!!
CUI.H2("Versuche,außerhalb des allokierten " +
"Speichers zu lesen");
IntPtr p3 = new IntPtr(p1.ToInt64() +
(long)MemSize + 2000000);
byte w3 = *(byte*)p3.ToPointer();
Console.WriteLine("Speicheradresse: " + p3 +
" Wert: " + w3);
Console.WriteLine("Besser nicht den Wert ändern!!!");
}
catch (Exception ex)
{
CUI.Error(ex.Message);
}
// Speicher wieder freigeben
NativeMemory.Free(m1);
}
}
İki not daha:
Try-catch blogu çökmeye karşı yardımcı olmuyor.
()
Haberin Sonu
Doğrudan bellek erişimi için .NET 6’da yeni bir sınıf var System.Runtime.InteropServices.NativeMemory ve sürüm 1.0’dan beri C#’ta bulunan işaretçi aritmetiği ile bağlantı. Bu dersi sadece bir derste yapabilirsiniz. unsafe-Bloğu kullan.
Aşağıdaki liste, doğrudan bellek erişiminin dikkate değer örneklerini göstermektedir:
- İlk olarak, çok fazla bellek kullanmak AllocZeroed() temelli.
- Bellek adresi ve mevcut değer (0 olmalıdır) çıktı olarak verilir.
- Adresteki değer 42 olarak değiştirilir.
- İmleç 10 hareket ettirilir.
- Değer 0 olmalı ve 42 olarak değişecektir.
- İşaretçi, ayrılmış belleğin dışındaki bir adrese taşınır.
Bu saçmalığı inşa etmezsen, sonunda kabul etmek zorunda kalırsın. NativeMemory.Free() ayrılmış belleği serbest bırakın.
static public void DirectMemoryAllocation()
{
unsafe
{
nuint MemSize = 1024 * 100;
for (int i = 0; i < 1; i++)
{
// Hole Speicher "ausgenullt" (alternativ: Alloc())
Console.WriteLine($"Allokiere nun {MemSize} Bytes...");
byte* m1 = (byte*)System.Runtime.InteropServices.
NativeMemory.AllocZeroed(MemSize);
CUI.H2("Wert Lesen und ändern");
IntPtr p1 = (IntPtr)m1;
Console.WriteLine("Speicheradresse: " + p1);
Console.WriteLine("Inhalt vorher: " + *m1);
Debug.Assert(*m1 == 0);
*m1 = 42;
Console.WriteLine("Inhalt nachher: " + *m1);
Debug.Assert(*m1 == 42);
CUI.H2("Schaue etwas weiter in den " +
"allokierten Speicher");
IntPtr p2 = new IntPtr(p1.ToInt64() + 10);
byte w2 = *(byte*)p2.ToPointer();
Console.WriteLine("Speicheradresse: " + p2 +
" Wert: " + w2);
Debug.Assert(w2 == 0);
byte* m2 = (byte*)p2.ToPointer();
Console.WriteLine("Inhalt vorher: " + *m2);
*m2 = 42;
Console.WriteLine("Inhalt nachher: " + *m2);
Debug.Assert(*m2 == 42);
try
{
// bei dem folgenden Unsinn des Entwicklers
// hilft in .NET Core CLR kein try-catch!!!
CUI.H2("Versuche,außerhalb des allokierten " +
"Speichers zu lesen");
IntPtr p3 = new IntPtr(p1.ToInt64() +
(long)MemSize + 2000000);
byte w3 = *(byte*)p3.ToPointer();
Console.WriteLine("Speicheradresse: " + p3 +
" Wert: " + w3);
Console.WriteLine("Besser nicht den Wert ändern!!!");
}
catch (Exception ex)
{
CUI.Error(ex.Message);
}
// Speicher wieder freigeben
NativeMemory.Free(m1);
}
}
İki not daha:
- Ayrılan belleği aşmaya çalıştığınızda, try-catch bloğu olsa bile, .NET 6’nın da temel aldığı .NET Core çalışma zamanı programı sonlandırır. Microsoft ayrıca şu belgelerde de açıklamıştır: “Yalnızca .NET Core: … bozuk işlem durumu özel durumlarından kurtarma desteklenmiyor.”
- Performansı artırmak için .NET’te bu tür doğrudan bellek erişimlerine gerçekten ihtiyacınız varsa, herkesin kendisi bilmesi gerekir. Microsoft, “düşük seviyeli kod ve algoritmalar için tasarlanmıştır. Uygulama geliştiricileri bunları nadiren kullanırdı, hatta kullanırdı.”

Try-catch blogu çökmeye karşı yardımcı olmuyor.
()
Haberin Sonu