fweaks fweaks - 1 year ago 78
C# Question

Starting a Timer Intermittently Deadlocks at Application Startup

I have an application with two separate GUI threads, and the main Form is run on each thread. (This is to allow simultaneous independent users on different screens.)

Each of these windows has an InactivityTimer component, which is used to take the user back to the homepage after they have been inactive for a certain period of time.

The pertinent parts of the main function:

static void Main()
MainWindow form1 = new MainWindow(true);

//check that we have a second screen
if (Screen.AllScreens.Length > 1)
{ //Setup the second screen on its own thread and bind events between the two
System.Threading.Thread thread = new System.Threading.Thread(() =>
MainWindow form2 = new MainWindow(false);
form2.FormClosed += (o, e) =>
form1.Close();//close form1 when form2 closes. we dont need vice-versa because form2 is on a background thread.

/* Logic that binds events between the two forms*/

{ IsBackground = true };

The InactivityTimer:

public partial class InactivityTimer : System.Windows.Forms.Timer, IMessageFilter
public InactivityTimer()

public InactivityTimer(IContainer container)

private void Initialise()

public void ResetTimer()

public bool PreFilterMessage(ref Message m)
bool watching = /*logic that determines whether this is a message we are watching for (mainly mouse actions)*/;
if (watching)
return false;//do not stop the event being dispatched

When I start the application, one of the screens always shows up before the other, which is not unexpected. But sometimes (not always) when I interact with that screen before the other has shown up, the application just stops, as though deadlocked. The second screen never shows and the first screen stops responding to input.

If I 'Break All' in debug mode when this happens, the application is always stuck on the
in the
of the InactivityTimer.

I have seen similar behaviour once before with a timer that I believed was because it was sometimes being started before it's parent control's handle was created, and that was 'fixed' by not attempting to start the timer if IsHandleCreated was false.


a) I don't even know for certain that it wasn't just a change of the timing fixing it;

b) In this case, I'm fairly certain the parent handle is already created since the window is showing;

c) That same fix hasn't worked here.

I've been digging into this for a while now and getting nowhere. Even worse, I can't seem to replicate the issue in a pared down application. But I just can't imagine anything that would be getting in the way of a timer calling start on itself after stop worked just fine.

If anyone can please figure out what's going on here and/or figure out a fix for it that would be amazing.

Answer Source

I only just today lucked into figuring out what was going on, because the debugger suddenly stopped in a completely different place.

rory.ap was correct in the comments that only things like locks, etc. would cause such a deadlock. However when I was looking over my code, it just never clicked that Invoke acts like such a construct (wrt the UI thread), so I wasn't paying attention to these.

However today my attention was drawn to it and low-and-behold I have an Invoke inside a lock, which is causing a deadlock.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download