Don't call GC.Collect() without calling GC.WaitForPendingFinalizers()

Rule ND2205 .NET Framework Usage / System

Avoid direct GC.Collect() calls (see Remove calls to GC.Collect()). If you call it anyway, do:

GC.Collect();

GC.WaitForPendingFinalizers();

GC.Collect();

so finalizers execute and finalizable objects get cleaned properly. Matches methods calling GC.Collect() without GC.WaitForPendingFinalizers().

How to fix

If GC.Collect() is really needed, call GC.WaitForPendingFinalizers() properly.

CQLinq source

This rule is written in CQLinq, C# LINQ over the NDepend code model. It ships with every new NDepend project: you can read it, adapt it, or use it as a starting point for your own custom rules.

// <Name>Don't call GC.Collect() without calling GC.WaitForPendingFinalizers()</Name>
// <Id>ND2205:DontCallGCCollectWithoutCallingGCWaitForPendingFinalizers</Id>

warnif count > 0 

let gcCollectMethods = ThirdParty.Methods.WithFullNameWildcardMatch(
   "System.GC.Collect(*)").ToHashSetEx()

from m in Application.Methods.UsingAny(gcCollectMethods) where
  !m.IsUsing ("System.GC.WaitForPendingFinalizers()".AllowNoMatch())
select new { 
   m, 
   gcCollectMethodCalled = m.MethodsCalled.Intersect(gcCollectMethods),
   Debt = 10.ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Expl>
// The *{0}* calls *GC.Collect()*. If you really want 
// to maintain this call, it should also call *GC.WaitForPendingFinalizers()*.
//</Expl>

//<Desc>
// Avoid direct **GC.Collect()** calls (see *Remove calls to GC.Collect()*).
// If you call it anyway, do:
//
//   GC.Collect();
//
//   GC.WaitForPendingFinalizers();
//
//   GC.Collect();
//
// so finalizers execute and finalizable objects get cleaned properly.
// Matches methods calling *GC.Collect()* without
// *GC.WaitForPendingFinalizers()*.
//</Desc>

//<HowToFix>
// If *GC.Collect()* is really needed, call
// *GC.WaitForPendingFinalizers()* properly.
//</HowToFix>

.NET Framework Usage / System: all 12 items