簡體   English   中英

應該嘗試/捕獲在使用區塊內部還是外部?

[英]Should try/catch be inside or outside a using block?

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;
        }
    }
}

這實際上取決於您擔心被處置的資源 - 如果您指的是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();
}

正常情況下, finally塊將始終執行,這意味着,即使您在using捕獲/重新拋出異常,也會觸發Dispose調用。

因此從技術角度來看,內部與外部並不重要。

using塊用於確保一旦代碼超出using塊,就可以確保在using語句中聲明的對象處理(從詹姆斯先生建議的不明確的“立即處置”術語改為處置)。 不完全try/catch/finally的簡寫。 (請注意, 編譯器會將其解釋為try-finally

在你的例子中

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

根據具體情況,您可以考慮將try-catch塊放在using塊的內部或外部。

例如,如果您不需要多次using聲明中的項目(編輯:我的意思是,如果您在trycatch塊中需要該項目 - 感謝Cody Gray先生的輸入) -也就是說,你只需要它try ,我會建議使用using的內部塊try塊。

轉換為您的情況,它取決於var client是否同時用於trycatch塊。 如果是,則using應該在try-catch塊之外。 否則,它應該在try塊內。

通常,根據經驗,如果在trycatch塊中同時使用該項,則在try-catch外部僅聲明一次using

無論哪種方式都可行。 保證使用塊總是在退出時調用Dispose()方法 - 即使對於堆棧的進一步向下捕獲異常的堆棧,也是如此。

看看使用Statement(C#參考)

using語句確保即使在對象上調用方法時發生異常,也會調用Dispose。 您可以通過將對象放在try塊中然后在finally塊中調用Dispose來實現相同的結果; 實際上,這就是編譯器如何翻譯using語句。 前面的代碼示例在編譯時擴展為以下代碼(注意額外的花括號以創建對象的有限范圍):

沒有“正確的方法”,只有指導方針。 然而,我自己嘗試盡可能地將每個異常或任何代碼本地化,這意味着你應該拋出一個異常,但是在外面的某個地方,至少只要你不必讓你的異常通過不同的層泡。

就個人而言,我會將try / catch / finally放在using塊中。
這樣做的原因很簡單,即using塊本身不會拋出異常,至少不是根據我的經驗。 所以為了簡單起見,我會處理它們發生的異常。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM