Rom*_*kov 15 .net c# exception-handling using-statement
我们正在研究C#中的编码模式,我们希望在其中使用带有特殊类的"using"子句,Dispose()根据"using"主体是正常退出还是异常退出,其方法会有不同的含义.
据我所知,CLR会跟踪当前正在处理的异常,直到它被"catch"处理程序占用为止.但是,这些信息是否以任何方式公开以供代码访问并不完全清楚.你知道它是否,如果是,如何访问它?
例如:
using (var x = new MyObject())
{
x.DoSomething();
x.DoMoreThings();
}
class MyObject : IDisposable
{
public void Dispose()
{
if (ExceptionIsBeingHandled)
Rollback();
else
Commit();
}
}
Run Code Online (Sandbox Code Playgroud)
这几乎看起来像System.Transactions.TransactionScope,除了成功/失败不是通过调用确定x.Complete(),而是基于using身体是否正常退出.
Vol*_*erK 12
http://www.codewrecks.com/blog/index.php/2008/07/25/detecting-if-finally-block-is-executing-for-an-manhandled-exception/描述了一个"hack"来检测是否您的代码是否在异常处理模式下执行.它使用Marshal.GetExceptionPointers来查看异常是否"活动".
但请记住:
备注仅为编译器支持结构化异常处理(SEH)公开GetExceptionPointers.NoteNote:
此方法使用SecurityAction.LinkDemand来防止从不受信任的代码调用它; 只有直接调用者才需要具有SecurityPermissionAttribute.UnmanagedCode权限.如果可以从部分受信任的代码调用代码,则不要在没有验证的情况下将用户输入传递给Marshal类方法.有关使用LinkDemand成员的重要限制,请参阅Demand vs. LinkDemand.
这个问题不是答案,而只是说明我从未在实际代码中使用"接受"的黑客攻击,所以它仍然在很大程度上未经测试"在野外".相反,我们去了这样的事情:
DoThings(x =>
{
x.DoSomething();
x.DoMoreThings();
});
Run Code Online (Sandbox Code Playgroud)
哪里
public void DoThings(Action<MyObject> action)
{
bool success = false;
try
{
action(new MyObject());
Commit();
success = true;
}
finally
{
if (!success)
Rollback();
}
}
Run Code Online (Sandbox Code Playgroud)
关键点在于它与问题中的"使用"示例一样紧凑,并且不使用任何黑客.
其中的缺点是性能损失(在我们的情况下完全可以忽略不计),而F10 DoThings在我真正希望它直接进入时会踩到x.DoSomething().两者都很小.
| 归档时间: |
|
| 查看次数: |
2430 次 |
| 最近记录: |