Can blocking in Dispose()
method (synchronous variant) anyhow influence GC process?
Supposing:
Dispose
, just abusing the pattern to inject some code at the point of Dispose
callDispose
as a "normal" method, which also could "accidentally" be called by compiler generated code from some syntactic sugar constructs, like using (var i = new Something(...)){}
or using var i = new Something(...)
and if using
is not suitable for us (from any reason), we just call it directly;Dispose
execution, right?Dispose
at all and just collects any instance, when there are no references to it, regardless of Dispose
being called or not, right?Example of such class:
class DisposeBlocker : IDisposable
{
private Task localWork;
private Task remoteWork;
...
DisposeBlocker(Task work)
{
remoteWork = work;
}
void Dispose()
{
for (var i = 0; i < 1000000; ++i) {} // CPU Bound
Thread.Sleep(1000); // Should be ok too, right?
Task.Delay(1000).GetAwaiter().GetResult(); // Is this still ok? Thread pools, contexts, similar stuff...
Task.WhenAll(localWork, remoteWork).GetAwaiter().GetResult(); // Same as the previous one, right?
}
}
Correct.
If it has no finalizer, GC will not care about the Dispose
method.
This sounds like a big code smell, though: if Dispose
is necessary, I would imagine it would be desirable to ensure it is called in most cicumstances, ergo you need a finalizer. And finalizers MUST NOT BLOCK or throw an exception under any circumstances.
It's also unexpected for Dispose
to block either. So you really should avoid this kind of setup.