5

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?

4
  • in the debugger or in the release build? Commented Nov 1, 2013 at 0:16
  • 3
    Is the line in catch block generate exception? Commented Nov 1, 2013 at 0:16
  • Attach a debugger - with break on exceptions - and step through. Commented Nov 1, 2013 at 0:18
  • 5
    This isn't the best approach to the problem. Don't use a try/catch to replace logical control elements. You should check to see if cpusage contains a . and then take the appropriate action. Commented Nov 1, 2013 at 0:19

3 Answers 3

2

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/

Sign up to request clarification or add additional context in comments.

2 Comments

How could that handler throw an exception?
cpuLabel.Invoke((MethodInvoker)(() => cpuLabel.Text = "CPU: " + cpusage + "%")); Doesn't throw ArgumentOutOfRangeException
2

The issue is being caused by this code:

cpusage.Remove(cpusage.IndexOf('.') 

You need to ensure that cpusage has length and contains a '.' before attempting to call .Remove.

You can prove this by running a simple app test:

 var cpuusage = "0"; System.Diagnostics.Debug.WriteLine(cpuusage.Remove(cpuusage.IndexOf('.'))); 

This will throw the ArgumentOutOfRangeException exception.

If you modify the code to be:

 var cpuusageforlabel = "CPU: "; if (!string.IsNullOrEmpty(cpuusage)) { var index = cpuusage.IndexOf('.'); if (index != -1) { cpuusageforlabel += cpuusage.Remove(index); } else { cpuusageforlabel += cpuusage; } } else { cpuusageforlabel += "0"; } cpuusageforlabel += "%"; cpuLabel.Invoke((MethodInvoker)(() => cpuLabel.Text = cpuusageforlabel)); 

You address the exception and won't have to catch the argument out of range exception.

2 Comments

You haven't explained at all why catch(ArgumentOutOfRangeException) doesn't catch. The real issue, the OP already knew that AOORE was being thrown. That's why he wrote the catch.
@HansPassant: Sorry, I did not get that at all from the description of the issue or the code. The OP indicated explictly where the exception was being thrown and I thought that the issue was the OP didn't understand why it was still being thrown even though there was a catch statement (i.e. it's not being thrown out of the catch statement).
0

Most probable reason is that cpusage is null or empty or without .. So when you get exception and try to use same variable again, you get the second exception.

Check cpusage before using it and don't use catch the way you are using.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.