.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

implement iDisposable

15 REPLIES 15
Reply
Message 1 of 16
mpropst
825 Views, 15 Replies

implement iDisposable

i have a utility class that gets a reference to acad and acaddoc

this class hands the refs off to the classes that use them

when the app terminates i think i need to dispose of acad...

from tony he mentioned implementing idisposable but i'm not getting the syntax right

can anyone help?

 

<System.Runtime.InteropServices.ComVisible(False)> Public Class MCSUtil
    Implements IDisposable

    Private m_acadDoc As AcadDocument
    Private m_AcadApp As Autodesk.AutoCAD.Interop.AcadApplication = Nothing
    Sub Dispose()
        m_AcadApp = Nothing
        m_acadDoc = Nothing

    End Sub

 

that sub dispose isn't recognized as the dispose for IDisposable...how do i do that?

thanks

mark

 

15 REPLIES 15
Message 2 of 16
caddzone
in reply to: mpropst

Interface methods must be declared as Public.

 

If your class is running in another process, you don't need to

'dispose' acad. You can call Marshal.ReleaseComObject() to

release the reference to COM objects, but that will happen

anyway when your application terminates or when the next

garbage collection occurs after setting all variables that are

referencing the COM object to Nothing.

 



AcadXTabs for AutoCAD
Supporting AutoCAD 2000-2011


Message 3 of 16
mpropst
in reply to: caddzone

well it's driving me crazy why i can't get acad to close after running a dotnet app i'm testing

i don't know what else to try and apparently no one else has this problem.

 

i netload the dll, run, close acad, edit some changes in the vbproj, rebuild dll, get error cant' rewrite dll because another process has it open...look in task mgr and there's acad sitting there doing nothing but not closing.

grrrr

 

this doesn't happen every time but most times and it's about to drive me over the edge

🙂

 

thanks

mark

Message 4 of 16
caddzone
in reply to: mpropst

Why don't you just call AcadApplication.Quit() ?



AcadXTabs for AutoCAD
Supporting AutoCAD 2000-2011


Message 5 of 16
mpropst
in reply to: caddzone

I don't want to quit acad in my application.  I'm only closing it because i'm editing the app and need to close acad to rebuild the dll

Message 6 of 16
Paulio
in reply to: mpropst

Don't know if this'll help but I had a similar problem when automating Excel in my AutoCAD app. No matter what I did there was always an Excel process hanging around. I eventually discovered that it was because I had a variable that was still linked to an excel object that I hadn't disposed of (it was a variable I'd assigned the current worksheet to). Sloppy I know but I never said I was any good at this coding lark!

 

I'd say perhaps check that you don't have any variables that are still holding acad objects. If they're all gone then Tony's suggestion about the Marshal.ReleaseComObject should work (at least it worked for me).

 

hth

Message 7 of 16
mpropst
in reply to: Paulio

I'll check that, but according to several posts here in past when a sub ends the variable goes out of scope so at program end nothing should still be alive. ... emphasis on "Should" ..

also per previous posts from Tony, the .ReleaseComobject "should' not be necessary when run in acad process space...

it sure won't hurt to try though

i'll have to figure out where that goes in my code

Message 8 of 16

Would I be correct in saying that the only time that Marshal.ReleaseComObject() would really be required for a dll running in-process in autocad would be if the COM object holds a resource (file...etc) that you need released before futher code execution? -Chris

Message 9 of 16
caddzone
in reply to: mpropst

A COM object assigned to a variable will not be released when the

variable goes out of scope. It will be released when the next

garbage collection occurs, which could be any time after the

variable has gone out of scope. If the COM object is in the same

process as the code that uses it, then there is no issue with

releasing it, because it will not prevent the app from closing if

it is not released.

 

 



AcadXTabs for AutoCAD
Supporting AutoCAD 2000-2011


Message 10 of 16

ReleaseComObject() releases a COM object determinstically,

which in the case of using COM objects from the same process,

is usually not required. The notable exception is AxDbDocument,

because releasing it releases the lock on the DWG file.

 

A COM object will eventually be released during a GC, when

there are no longer any reachable references to it, if calls

to ReleaseComObject()/FinalReleaseComObject() are not

made.



AcadXTabs for AutoCAD
Supporting AutoCAD 2000-2011


Message 11 of 16

 


@chrisshoemaker4224 wrote:

Would I be correct in saying that the only time that Marshal.ReleaseComObject() would really be required for a dll running in-process in autocad would be if the COM object holds a resource (file...etc) that you need released before futher code execution? -Chris


 

 

One of the most overlooked reasons for objects not being disposed was cited by Tony.

 

"A COM object will eventually be released during a GC, when there are no longer any reachable references to it, ..."

 

The key phrase here is reachable references.  One of the mot common examples of an overlooked reachable reference is the InvocationList of an event delegate. When you subscribe to an object's event, you create a reference to that object.  In most cases this is not a problem.  A WinForm is a typical non-problem.  At least most of the time.  But, .....

 

If a class subscribes to events from an object declared and instantiated by an external class, then this can create a problem scenario.  Consider what happens if the publishing object has a longer lifetime than the subscriber.  A typical WinForm can declare controls, and subscribe to events.  When the form is closed, the declared controls are disposed.  Their InvocationLists point to methods on the form, which is being disposed.  Good.

 

But when the publisher is alive after the subscriber is made a candidate for the GC, guess what?  You got it.  The faithful GC sees a reachable reference from the publisher, and does not fully dispose of the subscriber object.  Again, from Tony.


"A COM object assigned to a variable will not be released when the variable goes out of scope. It will be released when the next garbage collection occurs, which could be any time after the variable has gone out of scope.

 

If the COM object is in the same process as the code that uses it, then there is no issue with releasing it, because it will not prevent the app from closing if it is not released."

 

The target methods on the publisher's InvocationList are still alive and well.  The event handlers in the disposal candidate's InvocationList are still in scope!  The GC will not dispose of the object until the publishing object gets disposed.  That second sentence describes the scenario of a WinForm disposing of its own controls pretty accurately.

 

The subscriber will not get disposed until it unsubscribes from the publisher.  Moral of the story is this.  When implementing IDisposable, make sure to unsubscribe to event associated with objects defined and declared by external classes.

 

Hope this helps. 

 

Rudy  =8^D   

Fooling computers since 1971. Mark best replies as answers.
Message 12 of 16

Ah...that explains it. I was calling ReleaseComObject in the dispose methods of other classes just because I read some else (non ACAD-specific) that you should though it seemed to work fine one way or the other. AxDbDocument is where I did run into some trouble with locked files because DWG files weren't being unlocked consistantly. As it turns out i've re-writting most of the AxDbDocument functionality using the managed libraries so i't become less of issue, but the whole thing makes a lot more sense now. Thanks all!

Message 13 of 16
Rudedog2
in reply to: mpropst

 


@mpropst wrote:

well it's driving me crazy why i can't get acad to close after running a dotnet app i'm testing

i don't know what else to try and apparently no one else has this problem.

 

i netload the dll, run, close acad, edit some changes in the vbproj, rebuild dll, get error cant' rewrite dll because another process has it open...look in task mgr and there's acad sitting there doing nothing but not closing.

grrrr

 

this doesn't happen every time but most times and it's about to drive me over the edge

🙂

 

thanks

mark


 

Are you using any threads?  Are they still running after your application has "closed"?  That is the prime scenario whereby a DLL can still "be in use" after the application has closed.

 

Rudy   =8^D

Fooling computers since 1971. Mark best replies as answers.
Message 14 of 16
caddzone
in reply to: Rudedog2

COM objects generally do not handle managed events directly,

so it would be extremely and unusually rare to find references

to them in a Delegate's callback chain.

 



AcadXTabs for AutoCAD
Supporting AutoCAD 2000-2011


Message 15 of 16
Rudedog2
in reply to: Rudedog2

What about .NET wrappers around COM objects? 

 

As I look through the API, I am starting to see a lot of wrappers around COM.  DisposableWrapper is a base class for Entity.  DisposableWrapper is everywhere.  It wraps MarshalByRefObject.  It is also a base class for Document, Transaction, Window, etc.

 

 

Fooling computers since 1971. Mark best replies as answers.
Message 16 of 16
caddzone
in reply to: Rudedog2

DisposableWrapper doesn't wrap COM objects, it wraps native C++ objects.



AcadXTabs for AutoCAD
Supporting AutoCAD 2000-2011


Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost