Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exception that is handled is still thrown?

My code:

public void CPUStats()
{
    var cpuCounter = new PerformanceCounter("Processor", "% Processor Time", 
                                                                     "_Total");
    var ramCounter = new PerformanceCounter("Memory", "Available MBytes");
    ramCounter.NextValue();
    cpuCounter.NextValue();
    System.Threading.Thread.Sleep(1000);
    string cpusage = cpuCounter.NextValue().ToString();
    string ramusage = ramCounter.NextValue().ToString();

    //Occurs here v
    try
    {
        //exception thrown here v
        cpuLabel.Invoke((MethodInvoker)(() => cpuLabel.Text = "CPU: " + 
                                   cpusage.Remove(cpusage.IndexOf('.')) + "%"));
    }
    catch(ArgumentOutOfRangeException)
    {
        cpuLabel.Invoke((MethodInvoker)(() => cpuLabel.Text = "CPU: " + 
                                                                 cpusage + "%"));
    }

    ramLabel.Invoke((MethodInvoker)(() => ramLabel.Text = "Free RAM: " + 
                                                             ramusage + "mb"));
}

At times my application will stop at the cpuLabel invoke and throw an "ArgumentOutOfRangeException" when it was handled and fixed in my code. I tried increasing the timer that activates the thread that activates CPUStats(), but to no avail.

Why would this happen?

like image 816
Chris Altig Avatar asked Oct 03 '22 13:10

Chris Altig


1 Answers

Update:

Sorry, I should read your code more carefully. Your try-catch wrapped the delegate invocation which may not in the current context of thread. I think what you want to do should be:

public void CPUStats() {
    var cpuCounter= .. 

    ... 

    MethodInvoker m=() => {
        try {
            cpuLabel.Text="CPU: "+cpusage.Remove(cpusage.IndexOf('.'))+"%";
        }
        catch(ArgumentOutOfRangeException) {
            cpuLabel.Text="CPU: "+cpusage+"%";
        }
    };

    cpuLabel.Invoke(m);

    ... 
}

Have a look of SynchronizationContext and also Control.InvokeRequired.

Again, avoid try-catch if there's a better way to check for possible errors.


@competent_tech's answer is good, but I'd like to add a little bit.

There are some cases that a try-catch block would still throw:

  1. You did not catch the exact exception it thrown

  2. The handler rethrows the original exception

  3. The handler causes another exception

In your case, it hits the catch block and did not rethrow the original one, that is, it met the third circumstance: the handler causes another exception.

If you can address the problem causes the exception and avoid it , then don't design it in this way.

Mr. Lippert wrote a good article about the exceptions, you might want to have a look at:

http://ericlippert.com/2008/09/10/vexing-exceptions/

like image 174
Ken Kin Avatar answered Oct 13 '22 07:10

Ken Kin