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

Vic*_*ber 8 c# exception-handling

using区块是简写形式,try/catch/finally我相信.在我的代码,我一直把一个try/catchusing块,这样我可以用我自己的记录器捕获和记录异常.

我最近一直想知道是否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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Ian*_*Ian 5

using块用于确保在代码离开块时立即处理语句中声明的对象(从模糊的“立即处理”术语更改为James 先生建议的处理)。它不完全是 的简写。(请注意,编译器将其解释为 try-finally但是)usingusingtry/catch/finally

在你的例子中

using (var client = new HttpClient())
{
} //client will be disposed at any time after this line
Run Code Online (Sandbox Code Playgroud)

视情况而定,您可以考虑将try-catch块放在块的内部或外部using

例如,如果你不需要使用在项目using申报多次(编辑:我的意思是,如果你需要的项目try和中catch块-感谢通过输入科迪Gray先生) -即是,你只需要它try,我建议在using块内使用try块。

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

一般来说,根据经验,如果项目在trycatch块中都使用,那么在块using之外只声明一次try-catch


Jam*_*mes 5

这真的取决于你担心被处置的资源 - 如果你指的是client你应该没事.我会解释为什么......

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

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

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();
}
Run Code Online (Sandbox Code Playgroud)

正常情况下,一个finally块将始终执行,这意味着,即使您在其中捕获/重新抛出异常using,您的Dispose呼叫也将被触发.

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