See the top rated post in this thread. Click here

Results 1 to 4 of 4

Thread: Unregistering Event Handlers (Design Question)

  1. #1
    Member
    Join Date
    2008-10
    Posts
    43
    Login to Give a bone
    0

    Default Unregistering Event Handlers (Design Question)

    This is more an overall design best-practices for AutoCAD/C#.NET than a specific coding problem. I'm still at the (re)design stage of my application.

    Suppose you're registering different events at the Application, Document Collection, and Document levels. Let's further suppose the Application and Document Collection event handlers get constructed/registered when the application is started. Obviously I want those objects to persist as long as the application is open (or until I'm done with them, at least).

    The Document event handler could be constructed/registered by the Document Collection event handler at the DocumentCreated event and disposed of at DocumentDestroyed... but should it? One could also have the Document-level event handler constructed by the Document Collection event handler at the DocumentBecameCurrent event, and then unregistered and disposed of at DocumentToBeDeactivated.

    As far as I can tell, the decision whether to do this is dependent on whether the resources for construction/destruction of the Document event handler outweigh the resources required to maintain the Document event handler when the document isn't active, right? But if I'm responding only to CommandWillStart or BeginDocumentClose events, then there won't be any events that I need to respond to while the document is inactive, right? Or in other words, what Document events can be triggered while the inactive?

    What I'm worried about is the all-too-common-at-my-firm situation where the user has 12 drawings open, and now I've got 12 Document event handler objects floating around. If the documents they are watching aren't active, are they using up much in the way of resources?

  2. #2
    Member
    Join Date
    2008-10
    Posts
    43
    Login to Give a bone
    0

    Default Re: Unregistering Event Handlers (Design Question)

    Let me first thank you for such a thorough response, Tony.
    Quote Originally Posted by tony.tanzillo View Post
    As far as the overhead of maintaining document- and editor-level events on multiple open documents, I have found that it is not even worth mentioning, and provided that the handlers for the events do not have high overhead, I leave document- and editor-level handlers intact for all open documents, and add and remove them in handlers of the DocumentCreated and DocumentToBeDestroyed events, respctively.
    In the time since I posted the OP, I've experimented with this myself and come to the same conclusion. It seems like there's a general design pattern here that's not specific to AutoCAD, but I'm admittedly lacking in the general application design background to say for sure. (I'm in the middle of transitioning to Career 2.0, as it were.)

    Quote Originally Posted by tony.tanzillo View Post
    There are obscure cases where events can fire on a document that is not active and on its Database, although they are very rare. For example, the document locking related events can fire when a document is not active. But, the command-related events and almost all Editor events will never fire on an inactive document, if that's what you want to know.
    Yeah, I was worried there was some "gotcha" corner case I'd missed. Glad to know I'm not barking up the wrong tree.

    Quote Originally Posted by tony.tanzillo View Post
    One thing worth noting about handling Command events, is that many of the the coding examples on through-the-interaface relating to using Command events, do not serve as good examples of how to use them efficiently, because they needlessly handle all command-related events continuously, when it is only necessary to monitor the CommandWillStart event continuously, and the end-command related event handlers can be added/removed temporarily.
    That seems obvious to me, now. But Kean doesn't seem to do this all the time and definitely warns against it(for example here, http://through-the-interface.typepad...g-back-th.html, which was an article I see you commented on). What's the motivation for Kean to register the end-command events "early" when he does it, then? I wasn't able to find an example. For purposes of my application it's not going to matter because I'm only working with CommandWillStart right now, but I'm curious as to your thoughts on that.

    Quote Originally Posted by tony.tanzillo View Post
    Here's an example that shows this pattern wrapped up a reusable base type that automates much of the 'grunt' work:
    Thanks for this and the other example.

  3. #3
    Member
    Join Date
    2008-10
    Posts
    43
    Login to Give a bone
    0

    Default Re: Unregistering Event Handlers (Design Question)

    Tony, if you don't mind, I have a follow up question on the CommandEventsSample that you posted. I've had a chance to dig through it in detail, and it looks like a more robust, generalized, and flexible solution than what I already have in place. And it makes adding a new command event reactor *very* easy.

    Right now I have the chain of events I described in the OP: when the assembly is initialized, it constructs my document collection events monitor. On Doc_Created, the document events monitor gets created for that document and registers the CommandWillStart event handler. I also have a project-specific "policy file" that gets deserialized from XML, and that policy object gets stored in each document's UserData on Doc_Created. The various CommandWillStart reactors (and a few custom commands) rely on this policy object to control their behavior. (The policy files are intended to be reasonably human-readable for the users and customizable per project, if you're wondering why I'd jump through the XML hoop.)

    Looking at your sample, I'm now trying to figure out whether I need the IDisposable interface to be inherited by my UserData-related classes. My understanding was that if you're dealing with managed code then you can let garbage collection clean up after you. On Doc_Destroyed, the UserData hash table associated with a document should be garbage collected, right? (Which then triggers GB on objects stored in it?) I think what's contributing to my confusion is that you have a couple DocData abstract classes that implement IDisposable and another that does not as far as I can tell (the comment on line 15-16 in DocData.cs seems to indicate otherwise, but I'm not seeing it). Where do you use one vs the other?

    Obviously, per the license on this sample, I could pretty easily just drop those classes in and use this as-is with a minimum of fuss (this isn't for distribution). But obviously it would be better for my education if I understood why you've done it this way. =)

  4. #4
    Member
    Join Date
    2008-10
    Posts
    43
    Login to Give a bone
    0

    Default Re: Unregistering Event Handlers (Design Question)

    Quote Originally Posted by tony.tanzillo View Post
    I think that comment is old/stale, because DocData doesn't implement IDisposable, and you generally don't need to implement that interface,
    unless you have some need to release unmanaged resources.
    Ah, the comment may very well be the source of my confusion. I was having trouble figuring out why I couldn't find the IDisposable interface! And you also have the DisposableDocData class that does implement IDisposable, and as you say, you would only use that if whatever you were sticking into UserData was using unmanaged resources.

    Quote Originally Posted by tony.tanzillo View Post
    If you have to load some XML or other data associated with a document, you can do that in Attach(), or you can defer it until the first time the data is actually needed/accessed. I would choose the latter, mainly because
    if my code doesn't need the data for some reason, I don't have to wait for
    it to be loaded.
    In this case I'd rather the external data already be handy when appropriate commands fire, rather than be constructed on-demand. The user is expecting n amount of time for a document load anyway, so adding the fetch of the XML and construction of that object isn't noticeable. But adding that time to the start of a command might be.

    Anyways, at this point I already have my event handlers and UserData classes coded up and working, although without the extensibility your two solutions (DocData and CommandEvents). At this point I probably won't backtrack through to implement the more extensible solutions, but I'll certainly keep them in mind if I end up extending what I've got.

    Thanks again for taking the time to share and discuss this.

Similar Threads

  1. Replies: 9
    Last Post: 2014-07-07, 02:40 AM
  2. Design Question
    By pstur1235341 in forum 3ds Max - General
    Replies: 1
    Last Post: 2010-11-30, 02:39 PM
  3. Event Handlers
    By michael.montagne in forum VBA/COM Interop
    Replies: 1
    Last Post: 2010-07-08, 06:28 PM
  4. Design Review Question
    By neil.woodhouse in forum Design Review - General
    Replies: 1
    Last Post: 2010-04-06, 01:50 PM
  5. Storefront Design Question
    By sroy in forum Revit Architecture - General
    Replies: 3
    Last Post: 2008-09-17, 09:25 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •