-
Notifications
You must be signed in to change notification settings - Fork 8
Description
Several finalizers end up accessing managed finalizable resources. An example would be FileDownloadLocation, which accesses DirectoryInfo through its finalizer.
00000020`208ff1d0 00007ffd`0f2dda49 mscorlib_ni!System.IO.__Error.WinIOError+0x119
00000020`208ff220 00007ffd`0f3d5875 mscorlib_ni!System.IO.FileSystemEnumerableIterator`1[[System.__Canon, mscorlib]].CommonInit+0x1a5
00000020`208ff4d0 00007ffd`0f3d5493 mscorlib_ni!System.IO.FileSystemEnumerableIterator`1[[System.__Canon, mscorlib]]..ctor+0x203
00000020`208ff570 00007ffd`0f2f227d mscorlib_ni!System.IO.DirectoryInfo.InternalGetFiles+0x5d
00000020`208ff5e0 00007ffc`de4a4ff9 UNKNOWN!MFilesAPI.Extensions.FileDownloadLocation.CleanTemporaryFiles+0x49
00000020`208ff630 00007ffc`de4a4f72 UNKNOWN!MFilesAPI.Extensions.FileDownloadLocation.Dispose+0x22
00000020`208ff670 00007ffc`de4a4f30 UNKNOWN!MFilesAPI.Extensions.DisposableBase.Finalize+0x10
In the stack above the FileDownloadLocation is being finalized and it ends up executing CleanTemporaryFiles that accesses the managed DirectoryInfo. When implementing the Dispose(bool) pattern, the types should not touch managed objects when the boolean parameter indicates the call is coming through the finalizer.
If the method call comes from a finalizer, only the code that frees unmanaged resources should execute. The implementer is responsible for ensuring that the false path doesn't interact with managed objects that may have been disposed. This is important because the order in which the garbage collector disposes managed objects during finalization is nondeterministic.
It's also worth noting, that in .NET 5/.NET Core the finalizers are skipped during application shutdown.