В нашей структуре есть некоторые ключевые объекты, которые имеют дескрипторы файлов или клиентские подключения WCF. Эти объекты IDiposable
, и у нас есть код проверки (с генерируемыми исключениями), чтобы гарантировать, что они правильно удаляются, когда они больше не нужны. (Только отладка, поэтому мы не хотим сбой при выпуске). Это не обязательно при выключении.
Вдобавок к этому у нас есть модульные тесты, которые запускают наш код, и поэтому мы ожидаем, что они потерпят неудачу, если мы забудем о таких утилизациях.
Проблема: в .NET 4.5.1 с исполнителем NUnit (2.6.3.13283) (или с ReSharper, или TeamCity) не запускается ошибка теста, когда возникает такое исключение в Finalizer
.
Странная вещь: использование NCrunch (с NUnit тоже), модульные тесты < strong> НЕОБХОДИМО потерпеть неудачу! (Что для меня локально, по крайней мере, я могу найти такие недостающие утилизации)
Это очень плохо, так как наша сборочная машина (TeamCity) не видит таких сбоев, и мы думаем, что все хорошо! Но запуск нашего программного обеспечения (в отладке) действительно приведет к сбою, показывая, что мы забыли утилизацию
Вот пример, который показывает, что NUnit не дает сбоев
public class ExceptionInFinalizerObject
{
~ExceptionInFinalizerObject()
{
//Tried here both "Assert.Fail" and throwing an exception to be sure
Assert.Fail();
throw new Exception();
}
}
[TestFixture]
public class FinalizerTestFixture
{
[Test]
public void FinalizerTest()
{
CreateFinalizerObject();
GC.Collect();
GC.WaitForPendingFinalizers();
}
public void CreateFinalizerObject()
{
//Create the object in another function to put it out of scope and make it available for garbage collection
new ExceptionInFinalizerObject();
}
}
Выполнение этого в средстве выполнения NUnit: все зеленое. Если вы попросите ReSharper отладить этот тест, он действительно войдет в Finalizer.