C# try/catch应该在using块的内部还是外部?
我相信,C# try/catch应该在using块的内部还是外部?,c#,exception-handling,C#,Exception Handling,我相信,using块是try/catch/finally的缩写。在我的代码中,我一直在using块中放置一个try/catch块,这样我就可以使用自己的记录器捕获并记录异常 我最近一直想知道try是否应该在外部,从而使用块封装 在我看来,我之前一直担心,如果抛出异常,那么using块将不会Dispose(),因为它已跳出块并进入catch处理程序。但我可能错了 有人能澄清一下,同时使用和try/catch的正确方法是什么吗 public HttpResponseMessage GetData(s
using
块是try/catch/finally
的缩写。在我的代码中,我一直在using
块中放置一个try/catch
块,这样我就可以使用自己的记录器捕获并记录异常
我最近一直想知道try
是否应该在外部,从而使用块封装
在我看来,我之前一直担心,如果抛出异常,那么using
块将不会Dispose()
,因为它已跳出块并进入catch处理程序。但我可能错了
有人能澄清一下,同时使用和try/catch
的正确方法是什么吗
public HttpResponseMessage GetData(string x, int y)
{
using (var client = new HttpClient())
{
try
{
// do stuff
return response.Result;
}
catch (Exception ex)
{
// Something has gone badly wrong so we'll need to throw
// Log the info
throw;
}
}
}
using
块用于确保在using
语句中声明的对象在代码脱离using
块后立即进行处置(从模糊的“立即处置”术语改为建议的处置)。它并不是try/catch/finally的缩写。(但请注意)
在你的例子中
using (var client = new HttpClient())
{
} //client will be disposed at any time after this line
取决于情况,您可以考虑使用< <代码>块> >代码> > catch > <代码>块。
例如,如果您不需要多次使用using
声明中的项(编辑:我的意思是如果您在try
和catch
块中都需要该项,谢谢您的输入)-也就是说,您只需要在try
中使用它,我建议在try
块中使用use
块
转换为您的情况,这取决于var-client
是否同时用于try
和catch
块。如果是,则使用的应在try catch
块之外。否则,它应该在try
块中
一般来说,根据经验,如果在try
和catch
块中同时使用该项,则在try catch之外仅使用一次声明。使用块保证总是在退出时调用Dispose()
方法-即使是在堆栈中捕获的异常的堆栈解缠也是如此
看
using语句确保即使在调用对象上的方法时发生异常,也会调用Dispose。通过将对象放在try块中,然后在finally块中调用Dispose,可以获得相同的结果;事实上,编译器就是这样翻译using语句的。前面的代码示例在编译时扩展为以下代码(注意额外的大括号用于创建对象的有限范围):
没有“正确的方法”,只有指导方针。但是我自己尽可能地本地化每个异常或任何代码,这意味着您应该在可以抛出异常的地方创建一个异常,但是在外部的某个地方,至少只要您不必让异常冒泡通过不同的层。这实际上取决于您担心被处置的资源是什么-如果您指的是客户机
,您应该没事。我会解释为什么
在我看来,我之前一直担心,如果抛出异常,那么using块将不会Dispose()处理我的资源,因为它已跳出块并跳入catch处理程序。但我可能错了
这不是它的工作方式,编译器可能会重写您的代码(可能效率更高),如下所示:
在正常情况下,finally
块将始终执行,这意味着,即使您使用
捕获/重试中的异常,也会触发您的Dispose
调用
因此,从技术角度来看,内部与外部实际上并不重要。就我个人而言,我会使用
块将try/catch/finally放在中。
原因很简单,就是using
块本身不会抛出异常,至少根据我的经验不会。因此,为了简单起见,我将处理发生异常的地方 如果有using
块,则不必使用try/catch。尤其不需要捕获异常并立即重新显示它。如果您只想记录异常,请订阅AppDomain.UnhandledException
事件。在这种情况下,我还会将其放入using块中。但是,正如其他人所说,没有正确的方法可以做到这一点。使用
块并不是try/catch/finally的简写。一个using
块用于在不再需要某个对象时自动处理该对象。如果您要抛出该对象,它是否会自动处理;里面?去一趟怎么样?我会对“立即处置”一词保持警惕,我明白你的意思,即Dispose
将被调用,但这肯定不能保证垃圾收集方面的立即处置。你说的“重新声明”到底是什么意思?在using语句中只声明了一次。@James啊,是的,因为没有更好的术语。。。还有更好的建议吗?我对此持开放态度。要不然,我就贴张便条?@CodyGray我的意思是,如果你在试球和接球区都需要它的话。。。然后它需要重新声明…@Ian我真的要去掉“立即”这个词
try
{
try
{
// do stuff
return response.Result;
}
catch (Exception ex)
{
// Something has gone badly wrong so we'll need to throw
// Log the info
throw;
}
}
finally
{
if (client != null)
client.Dispose();
}