CA2202: не удаляйте объекты несколько раз
TypeName |
DoNotDisposeObjectsMultipleTimes |
CheckId |
CA2202 |
Категория |
Microsoft.Usage |
Критическое изменение |
Не критическое |
Причина
Реализация метода содержит пути кода, которые могли стать причиной многократного вызова метода IDisposable.Dispose или эквивалентного метода Dispose (например, метода Close() для некоторых типов) для одного и того же объекта.
Описание правила
Правильно реализованный метод Dispose можно вызывать несколько раз, и при этом не создается исключение.Однако это нельзя гарантировать, и чтобы не допустить создания исключения ObjectDisposedException, не следует вызывать метод Dispose для какого-либо объекта более одного раза.
Связанные правила
CA2000: удалите объекты до того, как будет потеряна область действия
Устранение нарушений
Чтобы исправить нарушение этого правила, измените реализацию так, чтобы независимо от пути кода метод Dispose вызывался для объекта только один раз.
Отключение предупреждений
Для этого правила отключать вывод предупреждений не следует.Если известно, что можно безопасно вызывать метод Dispose для данного объекта несколько раз, его реализация может измениться в будущем.
Пример
Вложенные инструкции using (Using в Visual Basic) могут привести к нарушениям предупреждений CA2202.Если ресурс IDisposable вложенного внутреннего оператора using содержит ресурс другого оператора using, метод Dispose вложенного ресурса освобождает содержащийся в нем ресурс.При возникновении такой ситуации метод Dispose внешнего оператора using пытается во второй раз ликвидировать свой ресурс.
В следующем примере объект Stream , который создается во внешнем операторе using, освобождается в конце внутреннего оператора using в методе Dispose объекта StreamWriter, который содержит объект stream.В конце внешней инструкции using объект stream освобождается во второй раз.Второй выпуск является нарушением CA2202.
using (Stream stream = new FileStream("file.txt", FileMode.OpenOrCreate))
{
using (StreamWriter writer = new StreamWriter(stream))
{
// Use the writer object...
}
}
Чтобы устранить эту проблему, воспользуйтесь блоком try/finally вместо внешнего оператора using.В блоке finally убедитесь, что ресурс stream не равен null.
Stream stream = null;
try
{
stream = new FileStream("file.txt", FileMode.OpenOrCreate);
using (StreamWriter writer = new StreamWriter(stream))
{
stream = null;
// Use the writer object...
}
}
finally
{
if(stream != null)
stream.Dispose();
}