У меня есть куча методов, которые берут WPF WriteableBitmap
и читают его BackBuffer
напрямую, используя небезопасный код.
Не совсем ясно, должен ли я использовать GC.KeepAlive
всякий раз, когда я что-то делаюкак это:
int MyMethod(WriteableBitmap bmp)
{
return DoUnsafeWork(bmp.BackBuffer);
}
С одной стороны, в стеке MyMethod
остается ссылка на bmp
.С другой стороны, похоже, что мы полагаемся на детали реализации - это может компилироваться в хвостовой вызов, например, без сохранения ссылки bmp
в момент ввода DoUnsafeWork
.
Аналогично представьте следующую гипотетическуюcode:
int MyMethod()
{
WriteableBitmap bmp1 = getABitmap();
var ptr = bmp.BackBuffer;
WriteableBitmap bmp2 = getABitmap();
return DoUnsafeWork(ptr, bmp2);
}
Теоретически ссылка на bmp1
остается в стеке до тех пор, пока метод не вернется, но, опять же, похоже, что используется деталь реализации.Конечно, компилятор может объединить bmp1
и bmp2
, потому что они никогда не живут в одно и то же время, и даже если компилятор никогда этого не делает, JITter, безусловно, может, и, вероятно, делает (например, сохраняя их оба втот же регистр, сначала один, потом другой).
Итак, в общем: должен ли я полагаться на локальные / аргументы, являющиеся допустимыми ссылками на объект, или мне всегда следует использовать GC.KeepAlive
, чтобы гарантировать корректность?
Это особенно озадачивает, поскольку, по-видимому, FxCop считает, что GC.KeepAlive всегда плохой .