App Freezes when screensaver settings are changed in Windows 7 - System.Threading.Timer The Culprit?

I have a C # / TCP / Winform application that has been running for quite some time, but one of my users has discovered a problem that I can easily replicate, but I cannot solve the problem.

If the application is open in Windows 7, and the user then changes any parameter in the screensaver settings - whether it is the screen saver or the time - the application freezes and the user interface becomes unresponsive. Clicking anywhere on the form simply gets the ding system.

When the application starts through Visual Studio in debug mode, the problem ceases to exist, but one day, from within the VS, it returns to freezing.

After some mastering and testing, I seem to narrow my problem down to System.Threading.Timer, which runs once per second. I relentlessly parse what the timer does, and find that even if the timer event does nothing, it still blocks the application. If I turn off the timer in the code or cancel the timer in the application before changing the Screensaver settings, the application will return to the functionality after changing the screen saver (although it still freezes for about 2-3 seconds).

This code here seems to be all that is needed for the application to freeze (inside WinForm code):

    /// <summary>
    /// Starts the countdown timer for unit alerts
    /// </summary>
    private void startCountDownTimer()
    {
        Object timeState = new object();
        this._timerCall = new System.Threading.TimerCallback(this.countDown);
        this._countdownTimer = new System.Threading.Timer(_timerCall, timeState, 0, 1000);
    }

    /// <summary>
    /// Invokes the countdown logic for unit alerts
    /// </summary>
    /// <param name="state"></param>
    private void countDown(Object state)
    {
        // REMOVED AND STILL FREEZING
    }

Note that this freeze occurs even though the contents of countDown are commented out so that the timer does nothing but fire once per second.

, , , - . - "":

*** MAIN WINDOW ACTIVATED ***
*** MAIN WINDOW ACTIVATED ***

, EndTask. EndTask , , :

A first chance exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll
===================================
ERR: Invoke or BeginInvoke cannot be called on a control until the window handle has been created.
       at System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate method, Object[] args, Boolean synchronous)
   at System.Windows.Forms.Control.BeginInvoke(Delegate method, Object[] args)
   at System.Windows.Forms.Control.BeginInvoke(Delegate method)
   at Wcsg.UI.Windows.CadClient.client_MessageReceived(TcpMessageReceivedEventArgs mrea) in C:\Users\---------\Documents\Visual Studio 2010\Projects\Dispatch-DEVELOPMENT\CadClient\Forms\CadClientForm.cs
   at Wcsg.Net.Tcp.WcsgTcpClient.processStream(Int32 count)
   at Wcsg.Net.Tcp.WcsgTcpClient.performSocketRead(IAsyncResult ar)
---------------------

, , , , -, , , , .

, .

* *

Main , (. ) . :

[STAThread]
    static void Main(String[] args)
    {
        // check for other running CadClients
        bool createdNew = _mutex.WaitOne(TimeSpan.Zero, false);

        if (createdNew) // first-run, launch Status Monitor on load
        {
            List<String> newArgs = new List<string>(args);
            newArgs.Add("-SM");
            args = newArgs.ToArray();
        }

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        AppDomain currentDomain = AppDomain.CurrentDomain;
        Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

        // try to catch issue 13445 -- see testing notes
        CadClient cc = new CadClient(args);
        CadExceptionHandler ceh = new CadExceptionHandler(ref cc);
        currentDomain.UnhandledException += new UnhandledExceptionEventHandler(ceh.CurrentDomain_UnhandledException);
        Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(ceh.Application_ThreadException);

        Application.Run(cc);
    }

* * , Splashscreen:

    private void showSplashScreen()
    {
        WaitCallback wcb = new WaitCallback(doSplashScreen);
        ThreadPool.QueueUserWorkItem(wcb);
    }

    private void doSplashScreen(object state)
    {
        if (this._splash == null)
            this._splash = new SplashForm(this);

        this._splash.FormClosed += new FormClosedEventHandler(_splash_FormClosed);
        this._splash.Show();

        while (this._splash != null && !this._splash.WorkDone)
            Application.DoEvents();
        this._splash.Close();
    }

showSplashScreen() - InitializeComponents(). , . , udpates, . ( ), , SplashScreen .

+3
1

@HansPassant , showSplash / Application.Run, InitializeComponent. this.showSplash InitializeComponent() , , , .

+3

All Articles