Stop writing rude software! Use LASTINPUTINFO instead.
Can you imagine what life would be like it people behaved like software programs do?
You'd be working away on something when someone would interrupt, steal your attention, and demand a response. You'd be interrupted in the middle of sentences all the time and while you were dealing with one interruption someone else could come up and interrupt you again.
You wouldn't put up with people like that so why do you put up with software that behaves that way?
Windows itself is one of the worst offenders: the dreaded dialog that explains that updates have been installed and it wants to reboot, right this instant has caused me significant inconvenience in the past as it steals focus and then grabs the next return character and assumes I really did want to reboot right now, right in the middle of a blog post!
There really is no excuse for writing rude software. Windows includes an API called LASTINPUTINFO that can tell you if the user is busy typing or moving the mouse and you can delay your annoying toast pop-up, or worse that focus-stealing modal dialog until you think the user is ready for it. The C# code below shows how to use this API call to get a number of seconds since the last user input. Simply delay your notification or dialog until an appropriate time has passed (e.g. 5 seconds) and only then interrupt the user).
Background processing
Similarly if your background processing is hammering the disk drive you can make it more polite and throttle it back when the user is active on their computer. (You did, of course do all that background processing on a lower priority thread, didn't you!)
One other area you might want to consider is using BITS to download files instead of hammering their internet connection to fetch files in the background.
The Code
So here's the code you should use from today to make your software polite:
public static class Input
{
[DllImport("User32.dll")]
private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);
private struct LASTINPUTINFO { public uint cbSize; public uint dwTime; }
/// <summary>
/// How many seconds since last user input
/// </summary>
public static double SecondsSinceLastInput()
{
LASTINPUTINFO lastInPut = new LASTINPUTINFO();
lastInPut.cbSize = (uint)System.Runtime.InteropServices.Marshal.SizeOf(lastInPut);
GetLastInputInfo(ref lastInPut);
uint idle = (uint)Environment.TickCount - lastInPut.dwTime;
return idle/1000.0;
}
}