Larry Osterman's WebLog

Confessions of an Old Fogey
Blog - Title

Things not to do, Part 3: Don't call CreateFile on your Windows message pump thread.

Things not to do, Part 3: Don't call CreateFile on your Windows message pump thread.

  • Comments 13

Sometimes it’s not a big deal, but there are some situations where it’s disastrous to call CreateFile on a message pump thread.

The problem occurs because CreateFile might take a long time to complete.  Conceivably it could actually take HOURS (although that is highly unlikely).  And if you’re calling CreateFile on your message pump thread, you’re not pumping messages (since CreateFile is synchronous).  Which means your app freezes and you get the dreaded “(not responding)” on your window if the user attempts to interact with your app.

Why would it take so long?  Well, what happens if the file’s located on slow media?  Like a floppy – remember floppy disks?  They can spend several seconds spinning up, especially if the floppy is newly inserted in the disk drive. 

Another even more common cause is if the file in question is located on a network drive – the first thing that happens when you’re opening a networked file is a DNS lookup which can take several seconds to complete.  Then you need to contact the file server, which in turn has to authenticate the user, and then process the open, all of which may also take several seconds to complete. 

If the file being opened is a message mode named pipe, you might block until an instance of the pipe becomes available on the server end, which could conceivably be hours (whenever the current named pipe clients disconnect).

 

Bottom line: Don’t do ANY file I/O on your message pump threads; offload them to worker threads so you can make your app responsive.

 

  • If the file has been archived to remote storage (read: magnetic tape), then the delay will be extraordinarly long indeed.
  • How about the case where the user *expects* some, possibly lengthy, file operation to take place, and expects the operation to have completed when the UI is responsive again. In other words: handling 'Open...' and 'Save...' commands. Doing those inside the UI thread seems logical to me, isn't it?
  • This may be the case, but if you do this, you have to be prepared for your application to be totally unresponsive for minutes.

    Usually user's won't accept this.
  • > This may be the case, but if you do this, you have to be prepared for your application to be totally unresponsive for minutes.

    indeed.

    be aware theat "totally unresponsive" includes repainting the screen.
  • In my QA job (in fact it is one of the the company standards) we consider the behavior as buggy/not acceptable if the app stops responding for more than 11-15 secs.
    If a certain operation may take a long time, UI should indicate that the process is doing fine and is not hanged/looped etc (using progress bars or any sort of animations).
    And, of course, User should never see the "not responding" state near the app name in Windows Task Manager.
  • Larry,
    Are you telling us that MFC is buggy ? :-)
  • Byron: Absolutely. Maybe I wasn't strong enough when I said "unresponsive".

    Thenin, I'd say if an app is unresponsive for more than about 1 or 2 seconds, it's unacceptable, especially if it happens soon after a user interaction. I get this with IE on my wife's machine - it'll mysteriously hang, and I notice it immediately. It's QUITE frustrating.

    Serge: Does MFC actually open files in the UI thread?

    I wasn't aware of that. Heck, I didn't realize that MFC ever opened files. But then again, I don't tend to use the document model in MFC at all.

    And if it does, then yes, it's buggy.
  • MFC has the excuse of being originally developed in the Windows 3.1 days, where of course you couldn't run another task to open your files ;)

    Changing it now would probably break something obscure.
  • I think for most apps, it's not a big enough problem to justify the extra time to do the right thing, just showing an hourglass cursor is enough. But if you're writing Windows Explorer, you probably do want to get it right.
  • I certainly hope LH will fare better on the cases where there is media problem. What I find quite odd is that when plugging in SATA HDD, even the mouse pointer freezes for about 2 seconds - makes me really wonder is that caused on the driver/kernel/hardware or what. If the system HDD starts having problems, it would be nice if a) whole system would not just suddenly freeze b) there would be some user assignable 5 MB of memory available for recovery toolkit that could be used for emergency measures for raw accessing the soon-dead hdd (it could still be readable but not boot again for example).
  • Some things will get better, others won't.

    In the SATA case, if the mouse isn't moving, it sounds like there's some DPC routine that's taking too long - which is likely to be a driver problem.

    On the other hand, if you're opening a file that's been archived to tape, there is nothing in the world that can possibly make it go faster. If the file's not physically present and needs to be reloaded from a backup tape, it's going to take time to open the file, regardless.
  • One other comment about the media problem. Sometimes when there's a media problem, there's nothing you can do.

    If you're dealing with a hard disk with bad sectors on it, then it'll take several seconds before the hard disk gives up on the read. There are external constraints that can't be worked around in software.
  • 6/2/2004 9:22 AM Larry Osterman

    > If you're dealing with a hard disk with bad
    > sectors on it, then it'll take several
    > seconds before the hard disk gives up on the
    > read.

    For this part of it, this is true and it is an understatement. If a CD has bad blocks then the machine can hang for several minutes. But there are two other cases where Windows really is at fault.

    When attaching a USB hard disk, Windows Explorer hangs for at least several seconds. This sounds a lot like Joku's comment about SATA hard disks. (Notice though, this is completely unrelated to the matter of disconnecting USB floppy drives that I commented on elsewhere. The hang for several seconds is a mere nuisance and does not cause blue screens of death. If you get a choice of which issues to work on, this one is not a priority.)

    When an IDE cable picks up noise from unrelated faulty components (e.g. unwanted radio frequency transmissions from other machines in the same room), Windows 2000 has a really serious flaw that Windows NT4 didn't have. Suppose Windows is installed on a hard drive attached to the IDE primary master, such as drive C:. Suppose another drive is attached to the IDE primary slave, such as a CD. Suppose an I/O operation to the slave fails because of noise. Windows 2000 tries to write a log entry to the primary master, ON THE SAME CABLE. No blue screen, just a permanent hang. The only way out is to turn the power off and on. In Windows NT4 I don't know if it didn't log I/O errors the same way or if the driver was smart enough not to try writing a log entry when recovery had not been completed on the same cable, but anyway Windows NT4 used to survive the experience.
Page 1 of 1 (13 items)