CA2115: Wywołaj GC.KeepAlive gdy używasz zasobów natywnych
TypeName |
CallGCKeepAliveWhenUsingNativeResources |
CheckId |
CA2115 |
Kategoria |
Microsoft.Security |
Zmiana dzielenia |
Bez dzielenia |
Przyczyna
Metody zadeklarowane w typu z finalizatorów odwołuje się do IntPtr lub UIntPtr polu, ale nie wywołuje GC.KeepAlive.
Opis reguły
Kończenie znajdujących obiektu kolekcji Garbage, jeśli brak odwołań do niego w kodzie zarządzanym.Niezarządzany odwołania do obiektów nie uniemożliwiają wyrzucania elementów bezużytecznych.Ta reguła wykryje błędy, które mogą wystąpić, ponieważ niezarządzanego zasobu jest zatwierdzony podczas jest wciąż używany kod niezarządzany.
Zakłada się, że ta reguła IntPtr i UIntPtr pól przechowywania wskaźników niezarządzanych zasobów.Ponieważ celem finalizatorów zwolnić zasoby niezarządzanego, reguła zakłada, że finalizatorów zwolni niezarządzanego zasobu wskazywanej przez kursor pól.Ta reguła założono również, że metoda odwołuje się do pola wskaźnik do przekazania do niezarządzanego kodu niezarządzanego zasobu.
Jak naprawić naruszenia
Aby naprawić naruszenie tej zasady, dodać wywołanie KeepAlive do metody, przekazując bieżące wystąpienie (this w C# i C++) jako argumentu.Umieść wywołanie po ostatnim wierszu kodu, gdzie obiekt musi być chroniony przed wyrzucania elementów bezużytecznych.Natychmiast po wywołaniu KeepAlive, obiekt ponownie uznaje gotowy do wyrzucania elementów bezużytecznych, przy założeniu, że istnieją nie zarządzane odwołania do niego.
Kiedy pomija ostrzeżenia
Niektórych założeń, które mogą prowadzić do fałszywie sprawia, że ta reguła.Ostrzeżenie od tej reguły można pominąć bezpiecznie, jeśli:
Finalizatorów nie zwolni zawartość IntPtr lub UIntPtr pole odwołuje się metody.
Metoda nie przekaże IntPtr lub UIntPtr pola do kodu niezarządzanego.
Uważnie przejrzyj inne wiadomości przed wyłączając je.Ta reguła wykryje błędy, które są trudne do odtworzenia i debugowania.
Przykład
W poniższym przykładzie BadMethod nie zawiera wywołanie GC.KeepAlive , a zatem narusza reguły.GoodMethodzawiera kod poprawiony.
[!UWAGA]
W tym przykładzie jest pseudo-code, chociaż Kod kompiluje i wykonuje, ostrzeżenie nie jest uruchamiany, ponieważ niezarządzanego zasobu nie zostanie utworzony lub zwolnione.
using System;
namespace SecurityRulesLibrary
{
class IntPtrFieldsAndFinalizeRequireGCKeepAlive
{
private IntPtr unmanagedResource;
IntPtrFieldsAndFinalizeRequireGCKeepAlive()
{
GetUnmanagedResource (unmanagedResource);
}
// The finalizer frees the unmanaged resource.
~IntPtrFieldsAndFinalizeRequireGCKeepAlive()
{
FreeUnmanagedResource (unmanagedResource);
}
// Violates rule:CallGCKeepAliveWhenUsingNativeResources.
void BadMethod()
{
// Call some unmanaged code.
CallUnmanagedCode(unmanagedResource);
}
// Satisfies the rule.
void GoodMethod()
{
// Call some unmanaged code.
CallUnmanagedCode(unmanagedResource);
GC.KeepAlive(this);
}
// Methods that would typically make calls to unmanaged code.
void GetUnmanagedResource(IntPtr p)
{
// Allocate the resource ...
}
void FreeUnmanagedResource(IntPtr p)
{
// Free the resource and set the pointer to null ...
}
void CallUnmanagedCode(IntPtr p)
{
// Use the resource in unmanaged code ...
}
}
}
Zobacz też
Informacje
Inne zasoby
Implementing Finalize and Dispose to Clean Up Unmanaged Resources