• The Old New Thing

    If an asynchronous I/O completes synchronously, is the hEvent in the OVERLAPPED structure signaled anyway?

    • 12 Comments

    Yes.

    When an I/O completes (whether synchronously or asynchronously), the event is signaled and completion status notifications are queued. The Get­Overlapped­Result/Ex function can be used to wait on an I/O that has already completed; it will merely return immediately. If you ask Has­Overlapped­Io­Completed whether the I/O has completed, and the I/O completed synchronously, it will correctly report, "Yeah, of course it completed. Heck, it completed a long time ago!"

    In other words, you can logically treat the case of an asynchronous I/O request completing synchronously as if it had completed asynchronously. It just completes asynchronously before you even blinked.

  • The Old New Thing

    Weak references have no effect on object lifetime

    • 18 Comments

    The Weak­Reference class lets you retain a reference to an object while still permitting the object to be garbage collected. When that happens, then the Is­Alive property is false and the Target property is null. (Related discussion.)

    Note, however, that weak references do not alter the decision of the garbage collector whether or not an object is garbage. It merely lets you observe the garbage collector's decision.

    Some people think that Weak­Reference means "Treat this as a regular (strong) reference most of the time, but if there is memory pressure, then you can reclaim the object." This type of reference is called a Soft­Reference in Java, but the CLR has no analogous concept as far as I'm aware. In the CLR, weak references do not extend the lifetime of an object.

    It's sort of like the Prime Directive from Star Trek: Weak references follow a policy of non-interference with the natural course of the GC.

  • The Old New Thing

    Instead of trying to create a filter that includes everything, try just omitting the filter

    • 12 Comments

    The question was sent to a peer-to-peer discussion group for an internal program, let's call it Program Q. I'll add additional context so you can follow along.

    Hi, I'm trying to build a query that finds all issues owned by a particular user, regardless of which product the issue belongs to. I know that I can query for specific products by saying

    q select -owner bob -product LitWare
    q select -owner bob -product Contoso
    

    Is there a better way to do this than just running the query for every product in the database? It would be great to find all the issues at one shot instead of having to issue dozens of commands and combine the results.

    The person who submitted this question got so distracted by the -product filter, that they forgot that they could just omit the filter.

    q select -owner bob
    

    If you don't filter by product, then it finds everything regardless of the product.

    Enumerating all the products, then repeating the query for each product is some sort of anti-pattern. I don't know if it has a name, so I'll make one up. The long division anti-pattern performs an operation on a collection by arbitrarily breaking the collection into groups, then performing the operation on each member of each group, all this even though the grouping is unrelated to the operation.

    In C#, it would be phrased something like this:

    public void MakeUnavailable(string productId)
    {
        var stores = Inventory.Select(p => p.Store).Distinct();
    
        foreach (var store in stores) {
            foreach (var product in
                     from p in Inventory
                     where p.Store == store &&
                           p.ProductId == productId) {
                product.Available = false;
            }
        }
    }
    

    In words, we first dig through the inventory and collect all the unique stores. For each store, we go through the inventory again, looking for products from that store, and if the product is the one we want to make unavailable, set the Available property to false. (To avoid playing favorites, I used both fluent and query expression syntax.)

    Assuming the order in which the product is made unavailable is not important (and it doesn't appear to be, since we didn't sort the stores), the grouping by store is superfluous. You can just iterate across the entire inventory without regard for store:

    public void MakeUnavailable(string productId)
    {
        foreach (var product in
                 from p in Inventory
                 where p.ProductId == productId
                 select p) {
            product.Available = false;
        }
    }
    
  • The Old New Thing

    There is no longer any pleasure in reading the annual Microsoft injury reports

    • 22 Comments

    Microsoft is required by law to file reports on employees who have sustained injuries on the job. They are also required to post the reports in a location where employees can see them. These reports come out every year on February 1.

    Back in the old days, these reports were filled out by hand, and reading them was oddly amusing for the details. My favorite from the mid 1990's was a report on an employee who was injured on the job, and the description was simply pencil lead embedded in hand.

    Sadly, the reports are now computerized, and there isn't a place to describe the nature of each injury. It's just a bunch of numbers.

    Numbers are nice, but they don't tell a story in quite the same way.

  • The Old New Thing

    The audacity of selling things that don't belong to you

    • 8 Comments

    NPR some time ago reported on a most audacious scam: Selling someone else's property out from under them. But this guy was small potatoes, selling properties owned by churches and other non-profit organizations. The king in this category of fraud is Victor Lustig, the man who sold the Eiffel Tower... twice!

  • The Old New Thing

    I always do a double-take when I see the name Andrew Bynum

    • 16 Comments

    I always think, "Does he have teammates Andrew Byref and Andrew Byval?"

  • The Old New Thing

    Up and down often substitute for compass directions, but you have to know when you've taken it too far

    • 26 Comments

    The official curriculum for seventh grade students in the state of Washington includes Washington history and geography. My friend the seventh grade teacher typically includes as part of this curriculum an assignment wherein each student is assigned one of the state's counties on which to produce a brief report.

    It is common to substitute up and down for north and south when speaking informally, but it is also important to know when you've taken the substitution too far. One student's report on Pierce County began with the following sentence:

    Pierce County is at the bottom of Puget Sound.
  • The Old New Thing

    The commutative law for postage and its limitations

    • 9 Comments

    The college professor who carried on a letter exchange with a kind pensioner who proved that the speed of light could be exceeded told me of another letter exchange, this time with another professional mathematician.

    The letter came from England, and it accompanied some sort of document or artifact that the correspondent wanted the college professor to look over and return. The mathematician took the effort of including a stamped return envelope with the remark, "By the commutative law for postage, I have placed the same amount of postage on the return envelope as I have on the outgoing envelope."

    The professor, however, could not use the return envelope the correspondent provided. He explained, "Unfortunately, the commutative law for postage does not apply to correspondence between the United States and the United Kingdom due to events of slightly more than 200 years ago."

  • The Old New Thing

    How do I get the color depth of the screen?

    • 19 Comments

    How do I get the color depth of the screen? This question already makes an assumption that isn't always true, but we'll answer the question first, then discuss why the answer is wrong.

    If you have a device context for the screen, you can query the color depth with a simple arithmetic calculation:

    colorDepth = GetDeviceCaps(hdc, BITSPIXEL) *
                 GetDeviceCaps(hdc, PLANES);
    

    Now that you have the answer, I'll explain why it's wrong, but you can probably guess the reason already.

    Two words: Multiple monitors.

    If you have multiple monitors connected to your system, each one can be running at a different color depth. For example, your primary monitor might be running at 32 bits per pixel, while the secondary is stuck at 16 bits per pixel. When there was only one monitor, there was such a thing as the color depth of the screen, but when there's more than one, you first have to answer the question, "Which screen?"

    To get the color depth of each monitor, you can take your device context and ask the window manager to chop the device context into pieces, each corresponding to a different monitor.

    EnumDisplayMonitors(hdc, NULL, MonitorEnumProc, 0);
    
    // this function is called once for each "piece"
    BOOL CALLBACK MonitorEnumProc(HMONITOR hmon, HDC hdc,
                                  LPRECT prc, LPARAM lParam)
    {
       // compute the color depth of monitor "hmon"
       int colorDepth = GetDeviceCaps(hdc, BITSPIXEL) *
                        GetDeviceCaps(hdc, PLANES);
       return TRUE;
    }
    

    If you decide to forego splitting the DC into pieces and just ask for "the" color depth, you'll get the color depth information for the primary monitor.

    As a bonus (and possible optimization), there is a system metric GetSystemMetrics(SM_SAMEDISPLAYFORMAT) which has a nonzero value if all the monitors in the system have the same color format.

  • The Old New Thing

    Why can't you use the space bar to select check box and radio button elements from a menu?

    • 17 Comments

    Nektar wants to know why you can't use the space bar to select check box and radio button elements from a menu.

    The short answer is "Because it's a menu, not a dialog box."

    The check mark and radio button are just visual adornments provided by the menu manager as a courtesy; they do not affect the behavior of the menu itself. Notice, for example, that there is no way to specify "radio button groups" in a menu, so the menu manager wouldn't know which items needed to be deselected when you select a radio button menu item. (I guess it could infer them from separators, but then you would have people saying "I want my radio button group to exclude item number 4, but I don't want to put a separator in between; that looks ugly.")

    And then how would a program reject an auto-selected check box or radio button? E.g., the user pushes the space bar to turn on Show the Widget Bar and an error occurs trying to show the Widget Bar. If the program displays an error dialog, that would dismiss the menu. So maybe the program would just silently re-uncheck the box, which leaves the user puzzled as to why the space bar "doesn't work" for turning on the Widget Bar. Or worse, what if hiding the Widget Bar causes the menu to reconfigure itself? (Maybe there are some menu items that are visible only when the Widget Bar is selected; if the user hides the Widget Bar, those menu items need to be deleted.) Windows doesn't have a precedent for menus reconfiguring themselves while they're being displayed. What if one of the items that gets deleted when you hide the Widget Bar is the menu item that contains the Widget Bar checkbox? ("I turned off the Widget Bar, and my menu disappeared!")

    That said, there is no technical reason these design issues couldn't be overcome. You could have a style like MF_GROUP that behaves like WS_GROUP to establish the scope of menu radio buttons; you could have some way to mark a menu item as "this is an unselected check box" or "this is an unselected radio button"; you could come up with a way for a program to reject a user's attempt to change the check box status; you could design a way for menus to be dynamically reconfigured while they are open; you could even design a way for menus to respond in some vaguely reasonable way when the item the user just selected gets dynamically deleted! But all of these features take effort, and they detract from the simple design of a menu as "Here's a list of things you can do. Pick one. Once you pick one, the menu dismisses." Every feature starts out with minus 100 points and needs to beat out the other 200 items on the list.

Page 388 of 448 (4,480 items) «386387388389390»