CA2115: вызывайте GC.KeepAlive при использовании собственных ресурсов
Товар | Значение |
---|---|
Идентификатор правила | CA2115 |
Категория | Microsoft.Security |
Критическое изменение | Не критическое |
Причина
Метод, объявленный в типе с методом завершения, ссылается на System.IntPtr поле или System.UIntPtr не вызывает System.GC.KeepAlive.
Примечание.
Это правило устарело. Дополнительные сведения см. в разделе "Устаревшие правила".
Описание правила
Сборка мусора завершает объект, если в управляемом коде нет дополнительных ссылок. Неуправляемые ссылки на объекты не препятствуют сборке мусора. Данное правило обнаруживает ошибки, которые могут возникать из-за завершения неуправляемых ресурсов, по-прежнему используемых в машинном коде.
Это правило предполагает, что IntPtr и UIntPtr поля хранят указатели на неуправляемые ресурсы. Поскольку цель средства завершения — освободить неуправляемые ресурсы, правило предполагает, что средство завершения освободит неуправляемый ресурс, на который указывает поля указателя. Это правило также предполагает, что метод ссылается на поле указателя для передачи неуправляемого ресурса неуправляемого кода.
Устранение нарушений
Чтобы устранить нарушение этого правила, добавьте вызов KeepAlive метода, передав текущий экземпляр (this
в C# и C++) в качестве аргумента. Поместите вызов после последней строки кода, в которой объект должен быть защищен от сборки мусора. Сразу после вызова KeepAliveобъект снова считается готовым к сборке мусора, если к нему нет управляемых ссылок.
Когда лучше отключить предупреждения
Это правило делает некоторые предположения, которые могут привести к ложным срабатываниям. Вы можете безопасно отключить предупреждение из этого правила, если:
Внимательно просмотрите другие сообщения, прежде чем исключить их. Это правило обнаруживает ошибки, которые трудно воспроизвести и отлаживать.
Пример
В следующем примере BadMethod
не включает вызов GC.KeepAlive
и поэтому нарушает правило. GoodMethod
содержит исправленный код.
Примечание.
В этом примере используется псевдокод. Хотя код компилируется и выполняется, предупреждение не запускается, так как неуправляемый ресурс не создается или не освобождается.
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 ...
}
}
}
См. также
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по