应该尝试/捕获在使用区块内部还是外部?

时间:2016-01-26 09:29:48

标签: c# exception-handling

我认为using块是try/catch/finally的简写。在我的代码中,我一直将try/catch放在 using块中,这样我就可以使用自己的记录器来捕获和记录异常。

我最近一直想知道try是否应该在外面,从而封装了using块。

在我看来,我以前一直担心如果抛出异常,那么using块将不会Dispose()我的资源,因为它已跳出块并进入catch处理程序。但我可能错了。

有人可以澄清一下同时使用usingtry/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;
        }
    }
}

5 个答案:

答案 0 :(得分:5)

这实际上取决于你担心被处置的资源 - 如果你指的是View -> Sidebar你应该没事。我会解释原因......

  

在我看来,我以前一直担心如果抛出异常,那么using块将不会Dispose()我的资源,因为它已跳出块并进入catch处理程序。但我可能错了。

这不是它的工作原理,编译器可能会重写你的代码(可能更有效),如下所示:

client

正常情况下,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(); } 块将始终执行,这意味着,即使您在finally内捕获/重新抛出异常,您的using电话也会被触发。

因此从技术角度来看,内部与外部并不重要。

答案 1 :(得分:4)

#include "stdafx.h" #include <iostream> extern int b; using namespace std; using namespace na; void play(){ static int a = 20; a = a + 10; cout << a << "\n"; b = b + 50; cout << b<<"\n"; //Scout << gupta; } int _tmain(int argc, _TCHAR* argv[]) { extern int f; play(); play(); play(); play();`enter code here` getchar(); return 0; } 块用于确保在using语句中声明的对象尽快处置(从Mr. James建议的不明确的“立即处置”术语更改为处置)代码不在using块中。 不完全是 using的简写。 (请注意the compiler interprets it as try-finally

在你的例子中

try/catch/finally

取决于具体情况,您可以考虑将using (var client = new HttpClient()) { } //client will be disposed at any time after this line 块放在try-catch块的内部或外部。

例如,如果您不需要多次使用using声明中的项目(编辑:我的意思是,如果您需要{strong>中的项目两者 {1}}以及using块 - 感谢Mr. Cody Gray的输入) - 也就是说,您只需要try,我建议使用catch块在try区块内。

转换为您的情况,取决于using是否同时用于tryvar client块。如果是,则try应该在catch块之外。否则,它应该在using块内。

通常,根据经验,如果在try-catchtry块中同时使用该项,则只在try之外声明catch一次

答案 2 :(得分:0)

无论哪种方式都可行。保证使用块总是在退出时调用Dispose()方法 - 即使堆栈没有引发异常被捕获到堆栈中也是如此。

查看using Statement (C# Reference)

  

using语句确保即使在对象上调用方法时发生异常,也会调用Dispose。您可以通过将对象放在try块中然后在finally块中调用Dispose来实现相同的结果;实际上,这就是编译器如何翻译using语句。前面的代码示例在编译时扩展为以下代码(注意额外的花括号以创建对象的有限范围):

答案 3 :(得分:0)

没有&#34;正确的方式&#34;在它上面,只有指导方针。但是我自己尝试尽可能地将每个异常或任何代码本地化,这意味着你应该抛出一个异常,但是在外面的某个地方,至少只要你不必让你的异常通过不同的层泡。< / p>

答案 4 :(得分:0)

就个人而言,我会将try / catch / finally放在using块内 原因很简单,using块本身不会抛出异常,至少不是我的经验。所以为了简单起见,我会处理它们发生的异常。