Good advice comes with a rationale so you can tell when it becomes bad advice


A customer asked for guidance in software design:

Is there an issue with creating and using COM objects from a UI thread which was initialized as STA? I have heard that it is a best practice to create and use COM objects on a background thread which is MTA. I would like to have some more information as to why. Any help?

(I still have trouble with the phrase best practice, especially when it is combined with the indefinite article: a best practice. It's like asking "Where is a tallest building?")

Good advice comes with a rationale so you can tell when it becomes bad advice. If you don't understanding why something should be done, then you've fallen into the trap of cargo cult programming, and you'll keep doing it even when it's no longer necessary or even becomes deleterious.

In fact, you will find that if you try to follow this advice to the letter, most shell objects will stop working, because shell objects tend to require an STA. But in the absence of a rationale document or any other context, it's unclear what the scope of the original advice was. Maybe it makes sense in context, but right now it's just a statement with no discussion or rationale.

When I asked the customer, "Can you provide the documents that provided this recommendation? Perhaps this 'best practice' makes sense in context. Right now, it's just a bare recommendation with no discussion or rationale."

The customer never wrote back.

Comments (20)
  1. Boris says:

    Actually it seems to me that there’s nothing wrong with "What is a tallest building?" in the same context in which "What is a best practice?" would be used. A tallest building is a building whose height is greater than any other in a particular geographical area. A best practice is the best way to do something in a particular domain. Goldman Sachs Tower is a tallest building, for example. Do you have a problem with the previous sentence? I don’t. It’s the tallest building in New Jersey.

  2. acq says:

    Allow me to ask even if I don’t work in that area:

    Am I right that I can actually have an application with a lot of threads and still initialize STA in main (UI) thread? Then I just have to do all COM stuff from main thread and everything’s fine?

  3. keith says:

    The best practice is to always use good practices.  

    I was wholly unprepared for the Gartner Group use of the term "best of breed" vs "enterprise", which I first encountered in the course of a presentation by my employer’s founder several months after starting.  

  4. Mark (The Other Mark) says:

    You probably never heard back from him because you answered his question.

    Lots of people latch on to "Best Practices" without knowing why. These people drive me nuts. If "Best Practice" is to use the Gumblefreem Optimizer… great, under what circumstances would you be better off with your Gumblefreem Unoptimized?

    Instead of blindly following other peoples blind advice, he asked the question. Is there an issue? Your followup question strongly implies "Nope, no issue. Sometimes it makes sense to do it the other way.", so if we was already faced with a situation where it seemed the best approach and best practice were two different items, there’s probably not a hidden trap that’s going pop up later.

  5. porter says:

    > Then I just have to do all COM stuff from main thread and everything’s fine?

    Depends entirely on what the COM objects do,  how you are using them, what the main thread is doing and how you share information with other threads.

  6. Brian Tkatch says:

    We separate buildings into groups. Within each group we show summary information, except for the tallest build in each group, which gets more information.

    When explaining this, i get asked, "show me a tallest building".

  7. Teo says:

    In various Microsoft blogs, I keep reading “a customer asked us”, “we told a customer to,” etc. Seriously, how did this mythical customer contacted you in the first place? For example, right now I am programming against the failover cluster API and it is a mess – the docs in MSDN, the examples in the platform sdk and the observed behavior in the debugger do not match at all. Not to mention that half the api in Server 2008 R2 is undocumented. So whom and how to ask for help?

    [The customers don’t contact the product teams directly; they go through a customer liaison. How do you get a customer liaison? Beats me. Maybe they have a support contract. Maybe they used one of the forums. -Raymond]
  8. Aaron G says:

    If the best practice is always the best practice, that would inevitably make it the only practice.  The very fact that there are other practices means that they must sometimes be better.

    I defy anyone to identify a practice that one can actually choose not to, er, practice, yet is still always the best choice.

  9. porter says:

    > Actually it seems to me that there’s nothing wrong with "What is a tallest building?"

    To show that Z is a Xest Y, choose any values of X and Y where Z is a Y, then keep reducing the scope until true.

  10. Brian Tkatch says:

    @Aaron G

    "I defy anyone to identify a practice that one can actually choose not to, er, practice, yet is still always the best choice."

    Under Windows? Reboot! :)

  11. Teo says:

    Cool, thanks for the answer.

  12. Van Houtte says:

    @Teo:

    My guess is that Raymond takes any group external to Windows as a customer of the Windows group. That (also) includes people from other groups at Microsoft most of whom don’t have access to Windows source code and/or who ask for help from the Windows team.

  13. Dale says:

    @Teo: I believe depends on the type of customer you are.

    At my last employer,we had our own Microsoft Technical Account Manager, and we were able to ask for help via the TAM.

  14. DysgraphicProgrammer says:

    I guessing that the customer dug out the documents with the recommendation and either could not find them or realized that the context did not apply. At that point he decided to stop wasting Raymond’s time.

    Personally I prefer to send an email that says: Oops. Never mind, the docs said only under conditions X, Y and Z when the moon is full and Jupiter is in the second house.  

    Especially since the receiver can ignore every thing after ‘never mind’ if he feels like it.  

  15. 640k says:

    What actually works is the *real life* is the right way to do a thing. Not by following some lousy docs. Both the docs and the api can have bugs which you have to compensate for anyway.

    One approach is to write a program which calls the api with all combinations of parameters. When the right (can be several) combination of calls and parameters is found, you know how to write your code.

  16. porter says:

    > One approach is to write a program which calls the api with all combinations of parameters.

    So we all need to use code-breaking supercomputers to crack the APIs rather than reading the documentation?

  17. porter says:

    >> One approach is to write a program which calls the api with all combinations of parameters.

    I forgot the best alternative, use open source then you can see what the function really does. Code inspection doesn’t have to stop at the code you write.

    [And if you look at the source code and you see, “Oh, the heap manager keeps the block size at offset -8 from the pointer it returns to me,” are you going to write code that relies on this? -Raymond]
  18. Teo says:

    Thanks for the answers, I’m talking about a small company – 20 people who just got our first MS partner certification.

    porter, open source is not a real solution to the problem. Although I have full access to our company code base, when I discover the problem is not in my code, I ask the guy who created the problematic code (or the code who is on the top of the call stack). This saves days which otherwise would be spent trying to understand why the code is written in this particular way. The docs are an indispensable tool.

  19. Mike Dimmick says:

    640k, porter, that is absolutely the WORST way to do it. Follow the docs. The documentation tells you what will be supported in the future. If you don’t do it that way, the way you have discovered may not work in the next version of Windows, the next service pack, the next security update. Windows is a changing target more than ever before; all you can rely on is what the developers have promised to support, which is what is in the documentation.

    Sometimes, the documentation is wrong. In that case, the safest thing to do is not to use that API. If you can’t avoid using the API, call support. You get a small number of free incidents with any boxed developer tool and with MSDN subscriptions.

    Open source tells you how the developer has chosen to implement it now, but that isn’t a contract. There’s absolutely no guarantee that what the owner of the function thinks is the contract matches what *you* think is the contract. They could easily break your app with the next version of their library if you don’t agree.

  20. Brian Tkatch says:

    “They could easily break your app with the next version of their library if you don’t agree.”

    But with no contract, there’s be little benefit to using the new library anyway, so you can stay with what you know works.

    [This assumes you have the liberty to choose which version of the library you want to use. Do you get to choose which version of /vmlinuz you want? What if you’re a plug-in and the host process prefers a different version of the library? What if a security fix to the library breaks your undocumented assumption? -Raymond]

Comments are closed.