C# 已处理的异常仍被抛出?
我的代码:C# 已处理的异常仍被抛出?,c#,exception,exception-handling,try-catch,C#,Exception,Exception Handling,Try Catch,我的代码: public void CPUStats() { var cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total"); var ramCounter = new PerformanceCounter("Memory", "Availa
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"));
}
有时,我的应用程序会在cpuLabel调用处停止,并在代码中处理和修复“ArgumentOutOfRangeException”时抛出它。我尝试增加激活CPUStats()的线程的计时器,但没有效果
为什么会发生这种情况?问题是由以下代码引起的:
cpusage.Remove(cpusage.IndexOf('.')
在尝试调用.Remove之前,需要确保cpusage具有长度并包含“.”
您可以通过运行一个简单的应用程序测试来证明这一点:
var cpuusage = "0";
System.Diagnostics.Debug.WriteLine(cpuusage.Remove(cpuusage.IndexOf('.')));
这将抛出ArgumentOutOfRangeException异常
如果将代码修改为:
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));
您可以处理异常,并且不必捕获超出范围异常的参数。最可能的原因是
cpusage
为null或空,或者没有。所以,当您得到异常并再次尝试使用相同的变量时,您会得到第二个异常
使用前请检查
cpusage
,不要使用catch
您正在使用的方式。更新:
对不起,我应该仔细阅读你的代码。您的try catch
包装了委托调用,该调用可能不在线程的当前上下文中。我认为你想做的应该是:
public void CPUStats() {
var cpuCounter= ..
...
MethodInvoker m=() => {
try {
cpuLabel.Text="CPU: "+cpusage.Remove(cpusage.IndexOf('.'))+"%";
}
catch(ArgumentOutOfRangeException) {
cpuLabel.Text="CPU: "+cpusage+"%";
}
};
cpuLabel.Invoke(m);
...
}
看看,还有
同样,如果有更好的方法检查可能的错误,请避免使用catch
@competent_tech的回答很好,但我想补充一点 在某些情况下,
try-catch
块仍会抛出:
catch
块,并且没有重新调用原始块,也就是说,它满足了第三种情况:处理程序导致另一个异常
如果您可以解决导致异常的问题并避免它,那么不要以这种方式设计它
Lippert先生写了一篇关于例外情况的好文章,您可能想看看:
在调试器或发布版本中?是否在
catch
block generate exception中?附加一个调试器(带有中断异常)并单步执行。这不是解决问题的最佳方法。不要使用try/catch替换逻辑控制元素。您应该检查cpusage
是否包含
,然后采取适当的操作。您根本没有解释为什么捕获(ArgumentOutOfRangeException)
不捕获。真正的问题是,OP已经知道AOORE正在被抛出。这就是为什么他写了这篇文章。@HansPassant:对不起,我根本没有从对问题的描述或代码中了解到这一点。OP明确指出了抛出异常的位置,我认为问题在于OP不理解为什么即使有catch语句(也就是说,它没有被抛出catch语句)。该处理程序如何抛出异常?cpuLabel.Invoke((MethodInvoker)()=>cpuLabel.Text=“CPU:+cpusage+”%”)
不会抛出ArgumentOutOfRangeException
@svick:谢谢你的提示。