在我学习的过程中,我偶然发现了这段代码。我在这里找到一个观察,即使作者正在使用“使用”块并创建“ts”对象,他在使用块内部使用try catch块,在catch部分中,他将对象“ts”显式调用Dispose方法。我觉得没必要。我不明白为什么他需要尝试并抓住这里,如果他必须“只处理对象”。
我的问题:
我们真的需要尝试抓住这里吗?在什么情况下,它将在这个例子中起作用?
使用“使用”块时,这种方式是否正确?它在GC过程中如何反应?它的开销对吗?
感谢两个问题是否可以以初学者可以理解的方式解释。
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();
}
}
答案 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)
当代码离开using
块时,相关对象ts
将在此处理。如果您执行以下操作,程序可以在没有处理对象的情况下离开此块的唯一方法是:
所以你不需要try / catch部分来正确处理对象。
尝试/捕获代码 的目的是吞下try块中代码中的任何异常。然而,处理电话是不必要的。
答案 3 :(得分:1)
根据我的理解,Dispose
电话没有理由。但是有try
catch
的原因。例如,如果UpdateData
调用失败,您可能需要进行一些调整然后重试。您可能还希望以不同的方式处理不同的异常,如果没有catch块,您将没有机会这样做。
答案 4 :(得分:1)
ts.dispose。 但是,如果你没有捕获异常,它将被抛出,如你的例子所示, catch块无声地吞下了异常。
答案 5 :(得分:1)
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
块中捕获异常。其中:
答案 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也会处理它。