I have seen lots of samples for resultbuffer objects. And I am not quite undestand where I have to dispose and where not to. I know It doens't hurt to dispose it anyways. But I am a woman and don't like to see extra unnessary lines in my application.Everything should be perfect. So someone explain it for me. Let's say below Funciton . Do I need a dispose ? Thanks . Regards .
Function test(ByVal Myobjid As ObjectId) As Boolean Dim MyDwg As Document = Application.DocumentManager.MdiActiveDocument Using Tr As Transaction = MyDwg.TransactionManager.StartTransaction Dim mydbObj As DBObject = Tr.GetObject(Myobjid, OpenMode.ForRead) If TypeOf mydbObj Is BlockReference Then Dim BR As BlockReference = TryCast(mydbObj, BlockReference) If BR.IsDynamicBlock Then Dim myrb As ResultBuffer = mydbObj.GetXDataForApplication("BlahBlah") If myrb.AsArray(1).Value.ToString.StartsWith("TEST") Then Tr.Commit() Return True End If End If End If Tr.Commit() End Using Return False End Function
Solved! Go to Solution.
In my opinion, yes, because it is not associated with the transaction, so your using statement will not dispose of it for you.
A bigger question for me is wether or not you should be disposing BR. mydbObj will get disposed by the using statement on your transaction, but I'm not sure about BR.
If you are using AuotCAD 2009 or later, I would suggest this:
Function test(ByVal Myobjid As ObjectId) As Boolean Dim MyDwg As Document = Application.DocumentManager.MdiActiveDocument Using Tr As Transaction = MyDwg.TransactionManager.StartTransaction 'Dim mydbObj As DBObject = Tr.GetObject(Myobjid, OpenMode.ForRead) 'If TypeOf mydbObj Is BlockReference Then If Myobjid.ObjectClass.Name = "AcDbBlockReference" then Dim BR As BlockReference = Tr.GetObject(Myobjid, OpenMode.ForRead) If BR.IsDynamicBlock Then Using myrb As ResultBuffer = mydbObj.GetXDataForApplication("BlahBlah") If myrb.AsArray(1).Value.ToString.StartsWith("TEST") Then Tr.Commit() Return True End If End Using End If End If Tr.Commit() End Using Return False End Function
The using statement will ensure the result buffer gets disposed wether it is your test value, or not. And using ObjectId.ObjectClass will allow you to type test for BlockReference without opening the object into memory. That is the part that only works in 2009 or later.
I will use your code. I didn't know about "ObjectClass" that is good trick .
But still I am confused. because once I removed all " disposed " function for result buffer and nothing happened. I worked with drawing for 2 hours . No crash . Audit didn't show anything. that I why I am not sure why do I need it ? if there is a need for dispose how and where phisically it will affect ? Do you know ?
For the most part, in my experience, not calling dispose will not cause a crash, unless you try to access the object after it falls out of scope which would cause a crash even if you did call dispose. The result of not calling dispose is that the object remains in memory, and it is not flagged for garbage collection.
My general rule to avoid that memory usage is to call dispose (or use a "using" directive) on every object that implements iDisposable, and I have even implemented iDisposable on some of my own classes. If you open an object using Transaction.GetObject(ID, openmode), then when you dispose the transaction, the object will be disposed as well, which is why you usually don't see explicit .Dispose calls on objects opened that way.
The exception to that rule is that you never call dispose on an object you didn't create. For example the active document, or the TransactionManager, or any Database that is open in the editor (unless you close it first).
If you are using Visual Studio, and you have the appropriate debug messages enabled, you will see messages in the output window that say "Forgot to call dispose?". My goal is to never see any of those messages.
Thanks chief, It was a great explanation and now I feel more comfortable. Didn't have a clue about all these. Like a blind person walking .
Just one more question and I am done. I work with Visual studio and and don't know how to activate appropriate debug message to tell me I have to dispose. I attach the setting I have as image. Let me know please if with this setting I should see that warning you mentioned.
The settings I was referring to are in a different location, in the options dialog (which you can to as shown below, from the debug pulldown, or also from the Tools pulldown ->Options) Then you have to make sure Show All Settings is checked in the bottom left. Go to Debugging->Output Window. image shows how mine were set.
Since I didn't see an option in there that jumped out at me for the dispose messages, I fiddled around a bit, and turned all of them off. Then I tested again, and I still got my "Forgot to call dispose?" message that you see in the image. Obviously I have a missing dispose call somewhere that I need to find But more importantly, you might not need to mess with these options because like I said, even with all of them off I still got my message.
I just noticed that if you right-click in the output window, you get direct access to toggle the "General Output Settings" plus one more called "Program Output". If you turn off Program output, pretty much everything goes away, including the Dispose messages.
Much appreciated .
I had them off. After I turned them on. I have 200 lines. My God ?!!
What did you do to me Chief ? Just Joking.
This is going to be a good weekend, finding all 200 Boo BOOs.
Thanks for all help
Keep in mind, if you forget to dispose something that is inside a loop, you will get one of those messages for every time through the loop, so you probably don't have 200 Boo Boos to find.
I'm not convinced that the ResultBuffer needs to be disposed.
For Reference :
I'd LIKE to see some qualified direction from AutoDesk regarding this issue.
class keyThumper<T> : Lazy<T>; another Swamper