Author Topic: Fenton Webb's advice re "To dispose or not to dispose"  (Read 75172 times)

0 Members and 1 Guest are viewing this topic.

SGP2012

  • Guest
Re: Fenton Webb's advice re "To dispose or not to dispose"
« Reply #105 on: August 13, 2012, 08:04:15 PM »
Hi Kerry,

How soon will this information be made public. ?

How soon will AutoDesk samples be brought up to date ?

I've not been following this thread, so I'm not completely clear which samples need bringing up to date in what way, and what information Fenton referred to that needs to be made public. However, ...

For specific documentation bugs, you can use the 'Comment?' link in the ObjectARX helpfiles to report an issue directly to our TechPubs team (if your default browser settings allow it to work properly  :|). Failing that, you're welcome to report documentation issues via DevHelp Online (if you're an ADN member) or on the appropriate Autodesk discussion group (if you're an ADN member or if you're not). As Fenton says, my DevTech team are much more actively monitoring the 'API' discussion groups these days.

And (because you know my email address, Kerry  :kewl:), you're welcome to send your list of documentation omissions and enhancement requests to me if you like, and I can pass them on to our TechPubs team. They have dedicated API documentation writers, who are quick to fix mistakes or omissions when they are brought to their attention.

The same applies for any bugs you find in the SDK samples (and if you'd care to summarize to me how the samples are outdated).

On a related note, I agree that the reference guide should do a good job of describing the basic contract for the API. But the days are gone when relatively static SDK and developer guiide samples are the only place people expect to look for code usage information. (Surely people only ever looked there because they couldn't find the information anywhere else)? The first places I (and, I suspect, everyone else on this forum) look for API examples and advice are: blogs (like Through the Interface or DevBlog), forums (like TheSwamp or the Autodesk forums), and websites (like the Autodesk Developer Center or StackOverflow) - or (more generally) we use Google, Bing or whatever is our search engine of choice.

I can only speak for my DevTech team within Autodesk - but this is why we have started (and will continue) to devote a lot of time to putting as much content as we can in the public domain - but (bugs aside) I'm not planning that we'll be retrofitting any information we post to the DevBlogs into the SDK documentation because to do so would be an expensive/inefficient use of people who could instead be creating much more content on our blogs, developer centers and forums.

HTH,

Stephen

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Fenton Webb's advice re "To dispose or not to dispose"
« Reply #106 on: August 13, 2012, 08:04:35 PM »
Hey Kerry

here's a tip for you, and all that read here... If you want more details about a function in .NET, simply find the corresponding function in the ObjectARX Reference... Specifically, for the question about OpenCloseTransaction and Polyline2d.ConvertTo - read AcDbPolyline::convertTo()... it states that the second parameter is used as an "Input Boolean indicating whether or not to do a handOverTo between the AcDbPolyline and the AcDb2dPolyline."

Another tip, if you read the ObjectARX Developers guide, you will understand much more about the underlying unmanaged code that the AutoCAD .NET API wraps.

Through necessity, I DO read the ARX ref.

Can you point to where it states that we shouldn't use a transaction with  Polyline2d.ConvertTo().

... just a side note.
I recently answered a question on the discussion group with a google link ; to be told
Quote
Sorry,It's hard for me to Search code from the English pages. In our country few people use CADnet so the information is few with Chinese language. In a word, My english is not very good. Thank you for your help.

This indicates to me that a major percentage of the worlds developers will never read this thread.

kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Fenton Webb's advice re "To dispose or not to dispose"
« Reply #107 on: August 13, 2012, 08:41:18 PM »

Thanks for the post Stephen.

Early in this thread I asked for a sample of the recommended way to code the example in Tony's first post.
That would be a good place to start.

Next would be some more complicated (RealLife) samples.
I haven't perused the SDK samples for a long time, so I'm not sure of the status there.

Regarding the doc's
This attachment would be a good place to start:


I know sometimes it seems that I do a lot of bitching about the documentation ; If you saw some of the emails I get from people wanting help,  or had a good look at the posts here at theSwamp or at the AutoDesk discussion group you'd get a better idea why I think it's important.

... and that's just about the stuff that is fundamental, let alone some of the naunces.

Best Regards
Kerry
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

owenwengerd

  • Bull Frog
  • Posts: 451
Re: Fenton Webb's advice re "To dispose or not to dispose"
« Reply #108 on: August 13, 2012, 08:51:24 PM »
I can only speak for my DevTech team within Autodesk - but this is why we have started (and will continue) to devote a lot of time to putting as much content as we can in the public domain - but (bugs aside) I'm not planning that we'll be retrofitting any information we post to the DevBlogs into the SDK documentation because to do so would be an expensive/inefficient use of people who could instead be creating much more content on our blogs, developer centers and forums.

<rant-mode>
That kind of thinking is dead wrong. Regardless of whether people look for information first via search engine, *all* programmers eventually need correct and accurate reference material from Autodesk to resolve any doubts, disputes, or confusion. Even if that requires 200 dedicated full-time Autodesk employees, the total outlay will still be much less to do it right and keep it correct than the eventual cost to your customers and third party developers of the confusion and inevitable massive waste of resources that results from not having such a baseline reference.

The move to almost useless HTML documentation is evidence that Autodesk will gladly throw developers under the bus on a whim or to save a buck, and I fear this is becoming the rule rather than the exception. I think it's great that Fenton and the others are shoveling stuff into the public domain, even if the stuff is raw and unfiltered and sometimes smells funny. But if nobody is manning the documentation stations, they should be working on documentation instead.
</rant-mode>

TheMaster

  • Guest
Re: Fenton Webb's advice re "To dispose or not to dispose"
« Reply #109 on: August 13, 2012, 09:14:54 PM »
Hey Kerry

here's a tip for you, and all that read here... If you want more details about a function in .NET, simply find the corresponding function in the ObjectARX Reference... Specifically, for the question about OpenCloseTransaction and Polyline2d.ConvertTo - read AcDbPolyline::convertTo()... it states that the second parameter is used as an "Input Boolean indicating whether or not to do a handOverTo between the AcDbPolyline and the AcDb2dPolyline."

Another tip, if you read the ObjectARX Developers guide, you will understand much more about the underlying unmanaged code that the AutoCAD .NET API wraps.

Hi Fenton, The native AcMgOpenCloseTransaction is to the best of my knowledge, not a public API, and is not documented in the native ObjectARX documentation. The OpenCloseTransaction is derived from Transaction, so that is the managed docs for it.


owenwengerd

  • Bull Frog
  • Posts: 451
Re: Fenton Webb's advice re "To dispose or not to dispose"
« Reply #110 on: August 13, 2012, 10:00:32 PM »
Not 30 minutes after posting my rant, I have a need to implement two new AcDbCurve members in a custom object that is derived from AcDbCurve. The new members are AcDbCurve::getAcGeCurve() and AcDbCurve::setFromAcGeCurve(). The ObjectARX reference includes the following very informative and helpful description: "This is getAcGeCurve, a member of class AcDbCurve." Google returns one hit to the the DevBlog which is no help at all. That's it, nothing else.

Therefore, I cannot implement these functions at all. I don't even know whether AcDbCurve implements them. Since only Autodesk knows how to implement them, it's not safe to call the functions on non-Autodesk objects because there is no contract, hence no way to know how to use them correctly. They are effectively unuseable, all because nobody could be bothered to write complete and correct documentation for them.

TheMaster

  • Guest
Re: Fenton Webb's advice re "To dispose or not to dispose"
« Reply #111 on: August 13, 2012, 10:38:01 PM »
Hey TT

Quote from: TT
"Well, I'm sure everyone would agree that using Open() and Close() (or Dispose) that way is going to become a problem if the code fails, so I guess it's about how one approaches the problem, and whether they plan for failure or always think about what'll happen in the event of a failure, or maybe they're the type that blissfully presumes that their code can't fail, and so they don't have to worry about what happens (e.g., what state the drawing is left in) if it does."

I don't agree, the using statement's Dispose is automatically called even when an exception is thrown. Also, there is a Cancel() method on an Opened entity which undoes the changes. This is the same function that a a StartOpenCloseTransaction.Abort() calls.


Hey Fenton.  I think you've misunderstood me. That is the whole point of my comment - that DBObject.Dispose() calls AcDbObject::close(), which is incorrect if an exception was thrown before the call to Dispose() is made by using().

That is precisely why Transaction.Dispose() calls Abort() rather than Commit(), if Commit() was not previously called.

Here is your 'nicer' code from that post:

Quote
Now my preferred way, Open/Close – see how much nicer it is?

Code - C#: [Select]
  1. public void OpenClose()
  2. {
  3.   Database db = HostApplicationServices.WorkingDatabase;
  4.   ObjectId msId = SymbolUtilityServices.GetBlockModelSpaceId(db);
  5.   using (BlockTableRecord btr = (BlockTableRecord)msId.Open(OpenMode.ForRead))
  6.   {
  7.     foreach (ObjectId id in btr)
  8.     {
  9.       using (Entity ent = (Entity)id.Open(OpenMode.ForWrite))
  10.       {
  11.         // do something
  12.       }
  13.     }
  14.   }
  15. }
  16.  
  17.  

Now I have shown the differences between the two styles...


You really haven't shown all the differences between the two styles.

There was one important difference, which is what happens when an exception terminates the code within the inner using() block. When using a transaction, all changes made to any object subsequent to starting the transaction will be rolled back.  In your example above, all changes made to all objects prior to the point where the exception terminates the code, will be left intact, and will not be rolled back, and that is because DBObject.Dispose() calls AcDbObject::close(), which commits changes.  So, all I was trying to point out was that your example above is functionally not equivalent to any of the others, all of which will roll back changes to all objects if the code is stopped by an exception.

So, if you want to compare apples with apples, your 'nicer' version must roll back changes to all entities processed by the foreach() loop when an exception is raised, which it doesn't do, making it functionally-incomplete, relative to what the methods that demonstrate the other 3 styles do.

And, for the much simpler case of using ObjectId.Open() to modify a single entity, here is what is actually required:

Code - C#: [Select]
  1.  
  2. using (Entity ent = (Entity)id.Open(OpenMode.ForWrite))
  3. {
  4.    try
  5.    {
  6.       // do something
  7.    }
  8.    catch
  9.    {
  10.       ent.Cancel();
  11.       ent = null;   // supress call to Dispose() and AcDbObject::close()
  12.       throw;
  13.    }
  14. }
  15.  
  16.  

And I think that snippet serves to show that using ObjectId.Open() to modify objects is not nearly as simple as it might at first seem, especially to someone who is used to thinking in terms of the Acad::ErrorStatus returned by most native API calls  :wink:.  It really does take a lot of mental 'retooling' to think about conveying failure using exceptions as it's done in managed code.

So if your response to this is 'well then you should use an OpenCloseTransaction', that's all fine and dandy except that someone neglected to think about the need to get the current/active OpenCloseTransaction without having to pass it around like a jug of moonshine.

« Last Edit: August 14, 2012, 03:30:42 AM by TT »

fentonwebb

  • Guest
Re: Fenton Webb's advice re "To dispose or not to dispose"
« Reply #112 on: August 14, 2012, 01:35:00 PM »
Hey TT

I personally believe that 99% of code you write for AutoCAD does not need to rollback anything. If it does, more often than not, it's because the code was not implemented correctly. That said, there are completely valid reasons for using nested Transactions with the rollback feature - do you have an example which shows what you are talking about?

Guys,

I'll repeat what I've said before, I personally like to use Open/Close, amongst other reasons, that's my style. Open/Close was in AutoCAD from ObjectARX V1, way before transactions - it works fine and even handles error conditions! For you guys, those who use Transactions, all I'm saying is, there is a big overhead for using "normal" Transactions, if you don't need the nested Transaction/Rollback functionality (99% don't) and you feel your app is running slower than you want, or you are curious if there will be a performance gain, then simply use StartOpenCloseTransaction - it's very simple advice really. If it doesn't work for you, just change it back - Alt+E->Find and Replace->Replace in Files->StartOpenCloseTransaction change to StartTransaction, Match Case, Whole word - simple............... :-)

SGP2012

  • Guest
Re: Fenton Webb's advice re "To dispose or not to dispose"
« Reply #113 on: August 14, 2012, 01:44:58 PM »
How long do we have to go until we break the record for the longest thread on TheSwamp? Is that within reach here, do you think?  :evil:

@Kerry - So your gripe in that specific example is about the AutoCAD .NET Developers Guide.  That was originally produced to help VBA developers when switching to .NET - that's why it has all the comparisons with VBA in it. I'll pass on your request for mention of OpenCloseTransactions, but there are a lot of other APIs that are not included in the Developers Guide. I don't believe that it will ever be possible to include a section on every AutoCAD API in that developers guide (or in the ObjectARX developers guide). It seems that our difference of opinion is that you feel the developers guide should endeavor to do that, whereas I think it should give people the basics people need to get started and then those same people can find more advanced info elsewhere (like here).

@Owen - Kind of the same answer. Again, we'll have to agree to disagree. I don't believe its possible for us to include the answers to every question that every developer ever has in our documentation. At least not without publishing the AutoCAD source code - which isn't going to happen. So it doesn't matter how many people we employ to write formal documentation, advanced developers will always want to know something we've not written down. Again, that's why my team are actively increasing their engagement in the public domain. Your complaint about searching doesn't worry me since we've only been doing this for a couple of months. But our ultimate goal is that every time my team answer a new (non-confidential) question, the information we provide will be publicly searchable. And if someone can't find the answer to their question by searching, then they'll get an answer if they ask on the correct Autodesk discussion group - that answer could come from my team, but is just as likely to come from one of the excellent (non-Autodesk) programmers who generously give their time and knowledge to help others on those forums (and on this one, of course   :angel:). If you don't see us making progress towards this goal during the next year, then you're welcome to come and throw a custard pie in my face at my 'Meet the Experts' panel session at AU next year :ugly:. (But you'll have to pay for the AU registration and for the custard pie  :laugh:).

(I'll also comment in passing that a big reason we have some gaps in our documentation is because we expose such a large public API. I'm glad its that way around).

And just to reiterate my offer - If someone is interested in sending me a list of documentation omissions and bugs (ideally in order of priority), then I'm very happy to pass it on for you.

dgorsman

  • Water Moccasin
  • Posts: 2437
Re: Fenton Webb's advice re "To dispose or not to dispose"
« Reply #114 on: August 14, 2012, 02:48:04 PM »
...whereas I think it should give people the basics people need to get started and then those same people can find more advanced info elsewhere (like here).

I can understand the limited ability to not cover everything in the finest detail and I'm fine with that.  But the documentation still needs to have a good grounding in the basics.  If you need to go through the advanced sections of the help files just to understand the basics, I wouldn't consider that a good design.  Same idea with the discussion forums - I shouldn't need to consult the actual AutoDesk developers for Transaction information.  Right now the documentation doesn't cover the basics as well as it could (and probably should).  Its hard to make any suggestions when the questions themselves aren't known.

For the highly advanced issues, a discussion-group, question/answer format is better because it can cover a lot of the nuances a conventional help system cannot.  But as they say the Internet is Forever; somebody searching could find old threads which are now obsolete first, before newer threads which cover those same issues.  With the (in)correct search criteria its possible to completely filter out the newer, correct, answers.
If you are going to fly by the seat of your pants, expect friction burns.

try {GreatPower;}
   catch (notResponsible)
      {NextTime(PlanAhead);}
   finally
      {MasterBasics;}

TheMaster

  • Guest
Re: Fenton Webb's advice re "To dispose or not to dispose"
« Reply #115 on: August 14, 2012, 04:29:39 PM »
Hey TT

I personally believe that 99% of code you write for AutoCAD does not need to rollback anything. If it does, more often than not, it's because the code was not implemented correctly. That said, there are completely valid reasons for using nested Transactions with the rollback feature - do you have an example which shows what you are talking about?


Well, I personally disagree with that. Even LISP programmers are programmed to think in terms of rolling back all changes their LISP commands make if an error occurs. This goes back to my comment about writing code with the assumption that Murphy's law prevails, and that one should always consider what the user will be left with in the event the application fails.

We can find countless examples of cases where custom commands perform a series of steps that make incremental changes to the drawing, which would be invalid or dependent on the operation having completed successfully, and shouldn't be left intact if that doesn't happen.  I think the folks here can easily relate to that, and their routine use of Transactions for ensuring that the changes are completed successfully or rolled back entirely bears witness to it.

Quote
Guys,

I'll repeat what I've said before, I personally like to use Open/Close, amongst other reasons, that's my style. Open/Close was in AutoCAD from ObjectARX V1, way before transactions - it works fine and even handles error conditions! For you guys, those who use Transactions, all I'm saying is, there is a big overhead for using "normal" Transactions, if you don't need the nested Transaction/Rollback functionality (99% don't) and you feel your app is running slower than you want, or you are curious if there will be a performance gain, then simply use StartOpenCloseTransaction - it's very simple advice really. If it doesn't work for you, just change it back - Alt+E->Find and Replace->Replace in Files->StartOpenCloseTransaction change to StartTransaction, Match Case, Whole word - simple............... :-)


For any existing code that relies on ObjectId.GetObject(), it is not nearly as simple as you make it seem. The reason we use ObjectId.GetObject() in the first place, is to avoid the need to pass transactions around. So, if they are making use of that API, then one cannot simply replace StartTransaction() with StartOpenCloseTransaction() without existing calls to ObjectId.GetObject() failing.

SGP2012

  • Guest
Re: Fenton Webb's advice re "To dispose or not to dispose"
« Reply #116 on: August 14, 2012, 04:40:27 PM »
I don't disagree on the need for formally documentating basic information, dgorsman. I've already made the author of the .NET developers guide aware of this thread. He's going to look into beefing up the info on transactions, and also fixing the places in the sample code where he's 'new'ing DBObjects without a Using statement. He's currently compiling a task list for updating the developers guide, so now is a good time to respond to my invitation to put forward suggestions. Items already on the list are blocks and plotting.

BlackBox

  • King Gator
  • Posts: 3770
Re: Fenton Webb's advice re "To dispose or not to dispose"
« Reply #117 on: August 14, 2012, 05:57:52 PM »
Stephen,

If I might ask, will this same 'push' for clarifying the basic documentation also propagate verticals such as Civil 3D, and AutoCAD MEP, etc. or will this be relegated to AutoCAD?
"How we think determines what we do, and what we do determines what we get."

SGP2012

  • Guest
Re: Fenton Webb's advice re "To dispose or not to dispose"
« Reply #118 on: August 14, 2012, 06:44:40 PM »
My previous comments were about the AutoCAD API documentation, but I'm happy to pass on your requests/suggestions for other Autodesk products too.

TheMaster

  • Guest
Re: Fenton Webb's advice re "To dispose or not to dispose"
« Reply #119 on: August 14, 2012, 07:18:33 PM »
Not 30 minutes after posting my rant, I have a need to implement two new AcDbCurve members in a custom object that is derived from AcDbCurve. The new members are AcDbCurve::getAcGeCurve() and AcDbCurve::setFromAcGeCurve(). The ObjectARX reference includes the following very informative and helpful description: "This is getAcGeCurve, a member of class AcDbCurve." Google returns one hit to the the DevBlog which is no help at all. That's it, nothing else.

Therefore, I cannot implement these functions at all. I don't even know whether AcDbCurve implements them. Since only Autodesk knows how to implement them, it's not safe to call the functions on non-Autodesk objects because there is no contract, hence no way to know how to use them correctly. They are effectively unuseable, all because nobody could be bothered to write complete and correct documentation for them.

I agree completely, and the sad thing is that it doesn't take much to put the needed information into the topic, but the problem is that most of the docs are generated from embedded programmer comments and little more, so the programmer didn't do what was required.  Perhaps the programmer was incorrectly assuming the reader understood that the abstract AcDbCurve class defines no geometry and therefore can't implement those methods, which like many other methods of that class, must be implemented by derived types.

If this helps:

ObjectARX 2012 Reference
   What's New in ObjectARX for 2012
      New in Global Functions:

acdbAssignGelibCurveToAcDbCurve            This function takes an AcGeCurve3d and sets the specified AcDbCurve to be geometrically identical to the AcGeCurve3d.
acdbConvertAcDbCurveToGelibCurve      This function takes an AcDbCurve and returns an AcGeCurve3d that is geometrically identical to the AcDbCurve.
acdbConvertGelibCurveToAcDbCurve       This function takes an AcGeCurve3d and returns an AcDbCurve that is geometrically identical to the AcGeCurve3d.

So, if a custom curve class encapsulates an AcGeCurve3d, the above functions should help.