Sunday 15 February 2015

c# - How to properly dispose collection of unmanaged resources from finalizer? -



c# - How to properly dispose collection of unmanaged resources from finalizer? -

here illustration uncertain:

public class someclass : idisposable { ~someclass() { dispose(false); } public void dispose() { dispose(true); gc.suppressfinalize(this); } private bool _disposed; protected virtual void dispose(bool disposing) { if (!_disposed) { if (disposing) { // todo: release managed resources here... } // ?! safe enumerate dictionary here ?! foreach (var resource in _resources.values) releasebuffer(resource); _resources = null; _disposed = true; } } private dictionary<string, intptr> _resources; ... }

will safe enumerate managed dictionary in order release unmanaged resources?

is availability of dictionary uncertain since order in finalizers invoked not defined?

here quote taken msdn find confusing [1]:

the finalizers of 2 objects not guaranteed run in specific order, if 1 object refers other. is, if object has reference object b , both have finalizers, object b might have been finalized when finalizer of object starts. http://msdn.microsoft.com/en-us/library/system.object.finalize(v=vs.110).aspx

rather having dictionary of unmanaged resources, suggest having dictionary of independent wrapper objects, each of responsible guarding 1 unmanaged resource. if object holding dictionary abandoned , no other references exist wrapper objects, of wrapper objects finalized without needing involve dictionary in process. using such approach create easier sanely handle cases in exception occurs during object construction, , @ to the lowest degree somewhat-sanely deal situations object finds resurrected between time has been enqueued finalization , time finalizer runs [code can't expected run "correctly" in such cases, should avoid corrupting state of rest of system].

for example, code uses handle may acquire lock during utilize and, after use, check "disposeobjectasap" flag; if set, re-acquire lock , dispose object. finalizer should set flag , seek acquire lock; if acquires lock, should dispose object. if unable, fact set flag should imply code has lock destined check flag , clean object, finalizer doesn't have to. if finalizer runs prematurely, may release resources thread going need, causing actions on other thread fail, finalizer won't release resources while thread using them or disposing them, since releasing resources in situations cause massive scheme corruption.

c# .net collections dispose idisposable

No comments:

Post a Comment