Transactions and disposing of .NET objects

 Hello guys,


Consider following code:
     var document = Application.DocumentManager.MdiActiveDocument;
            var database = document.Database;
            using (var tr = document.TransactionManager.StartTransaction())
            {
                using (var bt = (BlockTable)database.BlockTableId.GetObject(OpenMode.ForRead))
                {
                    using (var ms = (BlockTableRecord) bt["*Model_Space"].GetObject(OpenMode.ForWrite))
                    {
                        var circle = new Circle(Point3d.Origin, Vector3d.ZAxis, 10.0);
                        ms.AppendEntity(circle);
                        tr.AddNewlyCreatedDBObject(circle, true);
                        circle.Dispose();

                        tr.Commit();
                    }
                }
            }

And I'm doing simply that, calling dispose method of my Circle. If you run this code in BricsCAD a NullReference exception will be thrown at transaction commitment. I searched the Reflector and I saw that calling Commit(), it dispose all objects associated with transaction. Looking at .net examples that arrives with BricsCAD installation I'm seeing that you DO NOT dispose newly created objects too. 

So, I would ask for you opinion, is it OK to neglect the advice given by Autodesk and what will be the price - memory leaks?

Comments

  • with the line tr.AddNewlyCreatedDBObject(circle, true);

    you are handing over memory management of your circle to the transaction. so don't call circle.Dispose();, the transaction will do it for you

    Cheers :)

            

  • Angel,
    Additional to Daniels comment :
    The link quote is 
    >>> You use the  Dispose  method or the  Using  statement to signal when an object is ready for garbage collection. The  Using  statement in most cases is the preferred method, as it makes the proper calls to close and dispose of the object when it is no longer needed.

    Note the word or. 
  • Thank you, guys!

    I found douzaine related questions, but 2 of them are simply marvelous!

    Best regards, Angel!
  • Hello,

    Could you please check attached PDF file. On the left are values of AutoDelete property taken from BricsCAD and on the right are those from AutoCAD (when code is run on BricsCAD/AutoCAD).
    It seems that there are some inconsistencies between them. Could you, please, explain me, what this means and what am I supposed to keep in mind when writing code compatible for both ACAD and BCAD. I'm concerned about object destruction.

    Have a nice weekend!

    AutoDeleteProperty.pdf

  • Could you, please, explain me, what this means and what am I supposed to keep in mind when writing code compatible for both ACAD and BCAD. I'm concerned about object destruction.
    I haven't read the links you posted, but I think in theory you should just always call Dispose() (preferably via 'using(){}' pattern) for any object that implements IDisposable. In other words, it should be up to the underlying implementation to correctly destroy the unmanaged (and managed) objects. Of course it's possible that there are bugs in the BricsCAD implementation, but it's also possible that the differences are by design. At least in theory, I don't think the differences should affect your code.
    Regards
  • Try to use the Transaction to manage database objects (open / close / dispose).  If your just opening database objects for read, use the lightweight OpenCloseTransaction.   Every item that is, opened by, or added to, a transaction, is disposed when the transaction is disposed. 

     

    As mentioned above, you do not want to call dispose on an object that is owned by a transaction, or you will likely get an exception.

     

    Do not use an object , owned by a transaction, outside of the scope of said transaction, AutoCAD may allow the object to remain open for read, BricsCAD is more strict.

     

    Don’t worry about it too much, every object has a finalizer, and the garbage collector will do its job eventually. Example is ResultBuffer implements IDisposable,  but it’s not the end of the world if you don’t dispose it.

     

    Other objects implement IDisposable, but the dispose call does nothing, for example the Document class.

     

    Just stick with the Transaction pattern, you will be fine.

     

    Also, when debugging, if something is left open longer that it should be, you will get a “Forgot to call Dispose?”  warning in your VS output window.

    Cheers :)

     

  • < ... >

    Also, when debugging, if something is left open longer that it should be, you will get a “Forgot to call Dispose?”  warning in your VS output window.

    Cheers :) 


    Interesting, I wasn't aware of that !

    ... or perhaps I don't forget ...

    Thanks Dan,
    Regards,
  • Hello,

    Could you please check attached PDF file. On the left are values of AutoDelete property taken from BricsCAD and on the right are those from AutoCAD (when code is run on BricsCAD/AutoCAD).
    It seems that there are some inconsistencies between them. Could you, please, explain me, what this means and what am I supposed to keep in mind when writing code compatible for both ACAD and BCAD. I'm concerned about object destruction.

    Have a nice weekend!

    Regarding AutoDelete,
    Did you read Tony's answer to my query here:
  • @ Kerry

    Did you read Tony's answer to my query here:

    Yes I did and that's why I attached the pdf file above :)
    In BricsCAD, when AddNewlyCreatedDBObject is called, the value of AutoDelete property is not changed - it stays true for newly created object (for the circle) until the transaction is not committed, as opposite to AutoCAD. And thit is what bothers me so much - did ownership changed after calling AddNewlyCreatedDBObject in BricsCAD?
    I have a piece of code that is causing problems...

    Do not use an object , owned by a transaction, outside of the scope of said transaction, AutoCAD may allow the object to remain open for read, BricsCAD is more strict.
    I will rewrite the code causing problems according to your advice!

    Thank you very much guys!!!
  • Dear Angel,

    I think, that the problem with "AutoDelete"flag when object is added to database is somewhat serious ...
    we should (of course) be compatible with ARX here, and compatible with logic when ownership changes ...

    maybe you can open a SupportRequest, so that defect is logged ?
    If necessary you might add a piece of sample code, then easier for our analysts to reproduce.

    many greetings !
This discussion has been closed.