How bad threading design affects the user

I can’t help but notice awful threading designs manifested in some apps (which will remain nameless).  Here are some random grievances I have with these apps:

1. Don’t block the UI thread, especially not on file or network access.    When you block the UI thread in a GUI app, the app effectively hangs.

For example, one app has a “favorites menu” which contains a list or URLs. It has an icon next to each URL, which is determined by the URL’s content. Empirically, it looks like when I open the menu, it pings each of those URLs to get the content so that it can show the proper icon.  I know nobody would actually do something that horrible, but that’s what it looks like to the end-user. The net effect is that opening the menu causes the app to hang. The menu remains open as a top-level window even when you switch to a different app, which means it visually impairs the rest of your session.

Another app appears to have some “background autosave” feature which saves a backup copy of your current file next to the original. However, if you’ve opened the original over a network share, then this background save is now a background network access.

One challenge here is that it may be easy to call a function which calls another function, which eventually does the network access.

2. Don’t make everything Modal.  Although modal dialogs are simpler to use safely than modeless, there is a usability issue here. If a user needs to use two windows at once, don’t make them each modal. Imagine if Visual Studio’s Callstack window was modal. I think Visual Studio does a great job here of making the right things modeless, and providing a good docking infrastructure in the shell to manage the windows. 

What else would you add to the list?

Comments (12)

  1. Ali A says:

    I would add don’t use Resume/Suspend, and make sure you mark threads as background threads that should be running in the background.

  2. Marc Brooks says:

    "I know nobody would actually do something that horrible"

    You’ve obviously never used Windows Explorer to look at files on a network drive.  I see HUGE pauses when it tries to render the thumbnail view on the left "task area details".

  3. SameerV says:

    Use ThreadPool as much as possible Thread.Sleep etc. r expensive calls.

    Use Asynchronious calls for read & writes on IO Stream i.e. BeginRead, BeginWrite etc. it’s cool!!

  4. Sammer – along those lines, be careful of ThreadPool too. Some people seem to think that using a ThreadPool means they don’t have any threading problems. You can deadlock yourself by not using ThreadPool right.

  5. Chris says:

    Marc, I don’t think that’s really what Mike is talking about. Now if Windows Explorer blocked while it loaded that thumb, then that would seriously affect the user experince.

    Also, while it can take up to 10 seconds to load up a video thumb, I’ve only seen that with the first file I click on. I suspect it’s just because explorer has to init media player or somesuch.

  6. Fred says:

    Just had to add one more example- how about clicking on the "COM" tab within the VS Add References dialog.  I’ve learned to stay away from it, but it drives me crazy when I accidentally click on it!

  7. I’ve been suspicious that a certain application that has been doing network access on their UI thread….

  8. kaalikas says:

    explorer is the perfect example: if the network is slow or intermittent or the hard disk has been turned off by power management then when you try to navigate, open, right-click or do anything – explorer hangs… and often all explorer windows + the task bar hang – and the problem is exactly what is described here: the ui thread is blocked

  9. Jeff Stong says:


    Stall points out why doing network access on a UI thread is a horrible

    practice.  He…

  10. Mike, i was just wondering but what else can be a good practice other than to start a thread in case windows explorer is trying to fetch thumbnails for each picture.

  11. Sachin – the key rule is "Don’t block the UI thread". This includes:

    – don’t call blocking operations (like network or file operations) on your UI thread.

    – don’t have the UI thread do a blocking operation that could block indefinitely, including blocking on another thread that may hang.

    The better approach is to have a "worker" thread do the blocking work, and communicate asynchronously to the UI.

    Eg, if the UI wants to open a file, don’t have the UI call CreateFile (which may hang).

    Instead, have the UI ping a worker thread, and the worker thread then goes and opens the file. In the meantime, the UI is still pumping messages (like painting, and maybe evena  "Cancel" operation in case the file-open never comes back). When the worker thread finally opens the file, it can send a message to the UI thread.