Chr*_*tig 5 c# exception-handling exception try-catch
我的代码:
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"));
}
Run Code Online (Sandbox Code Playgroud)
有时我的应用程序将在cpuLabel调用时停止并在我的代码中处理并修复它时抛出"ArgumentOutOfRangeException".我尝试增加激活激活CPUStats()的线程的计时器,但无济于事.
为什么会这样?
更新:
抱歉,我应该更仔细地阅读您的代码。您try-catch包装了委托调用,该调用可能不在 thread 的当前上下文中。我认为你想做的应该是:
public void CPUStats() {
var cpuCounter= ..
...
MethodInvoker m=() => {
try {
cpuLabel.Text="CPU: "+cpusage.Remove(cpusage.IndexOf('.'))+"%";
}
catch(ArgumentOutOfRangeException) {
cpuLabel.Text="CPU: "+cpusage+"%";
}
};
cpuLabel.Invoke(m);
...
}
Run Code Online (Sandbox Code Playgroud)
查看SynchronizationContext和Control.InvokeRequired。
再次强调,try-catch如果有更好的方法来检查可能的错误,请避免这样做。
@competent_tech的答案很好,但我想补充一点。
在某些情况下,try-catch块仍然会抛出:
您没有捕获它抛出的确切异常
处理程序重新抛出原始异常
处理程序导致另一个异常
在您的情况下,它击中了catch块并且没有重新抛出原始块,也就是说,它遇到了第三种情况:处理程序导致另一个异常。
如果你能解决导致异常的问题并避免它,那么就不要这样设计。
Lippert 先生写了一篇关于例外的好文章,您可能想看看:
http://ericlippert.com/2008/09/10/veshing-exceptions/