当使用“使用”时,我们有任何情况包括我们处理对象的catch块而不执行任何其他操作

时间:2013-03-01 19:59:22

标签: c# exception-handling using

在我学习的过程中,我偶然发现了这段代码。我在这里找到一个观察,即使作者正在使用“使用”块并创建“ts”对象,他在使用块内部使用try catch块,在catch部分中,他将对象“ts”显式调用Dispose方法。我觉得没必要。我不明白为什么他需要尝试并抓住这里,如果他必须“只处理对象”。

我的问题:

  1. 我们真的需要尝试抓住这里吗?在什么情况下,它将在这个例子中起作用?

  2. 使用“使用”块时,这种方式是否正确?它在GC过程中如何反应?它的开销对吗?

  3. 感谢两个问题是否可以以初学者可以理解的方式解释。

    using (TransactionScope ts = new TransactionScope(TransactionScopeOption.RequiresNew))
    {
        try
        {
            ServiceReference1.Service1Client obj = new ServiceReference1.Service1Client();
            obj.UpdateData();
            ServiceReference2.Service1Client obj1 = new ServiceReference2.Service1Client();
            obj1.UpdateData();
            ts.Complete();
        }
        catch (Exception ex)
        {
            ts.Dispose();
        }
    }
    

11 个答案:

答案 0 :(得分:5)

这对我来说当然没必要。 using语句将编译为包含整个代码块的finally块,无论是否抛出异常,都会执行该块。

基本上,他正在写这个:

TransactionScope ts;
try
{
    ts = new TransactionScope(TransactionScopeOption.RequiresNew);
    try
    {
        ServiceReference1.Service1Client obj = new ServiceReference1.Service1Client();
        obj.UpdateData();
        ServiceReference2.Service1Client obj1 = new ServiceReference2.Service1Client();
        obj1.UpdateData();
        ts.Complete();
    }
    catch (Exception ex)
    {
        ts.Dispose();
    }
}
finally
{
    ts.Dispose();
}

哪个有点傻。他完全无视(或“吞咽”)异常是特别愚蠢的。 99.99999993%的时间,这是一个坏主意。

答案 1 :(得分:1)

在这个特定的代码片段中,catch子句唯一能做的就是防止异常冒泡。实际上,它忽略了异常。

这里的dispose方法用于回滚事务,但是一旦代码在using块之外,就会调用dispose,这仍然是不必要的。

答案 2 :(得分:1)

  1. 不,你不需要这里的捕获。
  2. 通过“这种方式”,我假设你没有提到try / catch块实现的双重处理。是的,这是正确的方法(丢失try / catch部分)。
  3. 当代码离开using块时,相关对象ts将在此处理。如果您执行以下操作,程序可以在没有处理对象的情况下离开此块的唯一方法是:

    1. 杀死该计划
    2. 终止帖子
    3. 所以你不需要try / catch部分来正确处理对象。

      尝试/捕获代码 的目的是吞下try块中代码中的任何异常。然而,处理电话是不必要的。

答案 3 :(得分:1)

根据我的理解,Dispose电话没有理由。但是有try catch的原因。例如,如果UpdateData调用失败,您可能需要进行一些调整然后重试。您可能还希望以不同的方式处理不同的异常,如果没有catch块,您将没有机会这样做。

答案 4 :(得分:1)

无论如何,当使用“using”时,隐式调用终止部分

ts.dispose。 但是,如果你没有捕获异常,它将被抛出,如你的例子所示, catch块无声地吞下了异常。

答案 5 :(得分:1)

using Statement

  

using语句确保即使调用Dispose也会调用   在对象上调用方法时发生异常。您可以   通过将对象放在try块中来实现相同的结果   然后在finally块中调用Dispose;其实这是怎么回事   using语句由编译器翻译。

是的,在您发布的代码中的异常块中处置是不必要的。

答案 6 :(得分:1)

通过using定义的任何对象都必须实现IDisposable。一旦它超出范围(意味着控制离开Disposed()块),该对象就是using,无论采用何种方式 - return语句,goto,异常因此,为了确保正确处理using变量,捕获异常是多余的。

此代码:

using ( MyDisposableObject x = new MyDisposableObject() )
using ( AnotherDisposableObject y = new AnotherDisposableObject() )
{
  x.Foo() ;
  y.Bar( x ) ;
}

与此代码完全相同

MyDisposableObject x = new MyDisposableObject() ;
AnotherDisposableObject y = new AnotherDisposableObject() ;
try
{
  x.Foo() ;
  y.Bar( x ) ;
}
finally
{
  x.Dispose() ;
  y.Dispose() ;
}

但是,有理由,您可能希望在using块中捕获异常。其中:

  • 实际上处理捕获的异常。
  • 记录并重新抛出捕获的异常。
  • 例如,故意吞下特定的异常,以允许继续执行。您可能希望这样做的原因包括,例如demanding permissions,以便了解您是否被允许做某事。如果需求失败,则抛出SecurityException。捕获允许您采取行动,例如,通知用户他们没有权限打开他们要求的文件。

答案 7 :(得分:1)

简短的回答是否定的。 TransactionScope实现了IDiposable,因此C#using语句将在执行代码块后自动调用Dispose()。

此上下文中try / catch块的用处是可能为某些类型的异常完成事务。

在大多数情况下,只需调用ts.Complete();作为using块中的最后一个语句。这可确保在抛出事务之前抛出的任何异常都会导致事务回滚。

答案 8 :(得分:0)

您不需要在using语句中调用Dispose。它为你处理。

如果你想在那里处理一些异常,在使用中使用try catch没有任何问题,只是不要进行处理。

答案 9 :(得分:0)

不,那个特定的try..catch完全没用(好吧,无论如何,无论如何, 默默地吃掉你可能遇到的任何例外)。

请注意,这不是等价的,using子句更强,因为它甚至在成功时调用Dispose,因为它扩展为try..finally而不是{{1} }}

答案 10 :(得分:0)

1)如果您要真正处理异常或记录并再次抛出它,您只需要try / catch。 try / catch的任何其他用途都是不好的做法。在这种情况下,您所做的只是处置ts,因此您不需要它,因为您在using区域内。

2)不,你不需要调用dispose:即使有异常,使用block也会处理它。