使用块从异常中检测到Dispose() [英] Detecting a Dispose() from an exception inside using block

查看:177
本文介绍了使用块从异常中检测到Dispose()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序中有以下代码:

  using(var database = new Database()){
var poll = //某些数据库查询代码。

foreach(poll.Questions中的问题问题){
foreach(问答中的答案.Answers){
database.Remove(answer);
}

//这是一个模拟错误的示例行。
抛出新的异常(deu pau);

database.Remove(question);
}

database.Remove(poll);
}

此代码像往常一样触发Database类Dispose()方法,此方法自动将事务提交到数据库,但这会使我的数据库处于不一致状态,因为答案被删除,但问题和投票不是。



有什么办法我可以在Dispose()方法中检测到它被调用,因为异常而不是正常的结束块,所以我可以自动回滚?



我不要手动添加一个try ... catch块,我的目标是将use块用作一个逻辑安全的事务管理器,因此如果执行是干净的或者如果发生任何异常,则它提交到数据库。 p>

你有什么想法吗?

解决方案

如其他人所说,您为此使用Disposable模式是导致您出现问题的原因。如果模式正在反对你,那么我会改变模式。通过提交使用块的默认行为,您假定每次使用数据库都会导致提交,这显然不是这样 - 特别是如果发生错误。一个明确的提交,可能与一个try / catch块组合将会更好。



但是,如果你真的想保持你使用的模式, / em>,可以使用:

  bool isInException = Marshal.GetExceptionPointers()!= IntPtr.Zero 
| | Marshal.GetExceptionCode()!= 0;您的Displose实现中的

(详细信息 here )。


I have the following code in my application:

using (var database = new Database()) {
    var poll = // Some database query code.

    foreach (Question question in poll.Questions) {
        foreach (Answer answer in question.Answers) {
            database.Remove(answer);
        }

        // This is a sample line  that simulate an error.
        throw new Exception("deu pau"); 

        database.Remove(question);
    }

    database.Remove(poll);
}

This code triggers the Database class Dispose() method as usual, and this method automatically commits the transaction to the database, but this leaves my database in an inconsistent state as the answers are erased but the question and the poll are not.

There is any way that I can detect in the Dispose() method that it being called because of an exception instead of regular end of the closing block, so I can automate the rollback?

I don´t want to manually add a try ... catch block, my objective is to use the using block as a logical safe transaction manager, so it commits to the database if the execution was clean or rollbacks if any exception occured.

Do you have some thoughts on that?

解决方案

As others have said, your use of the Disposable pattern for this purpose is what is causing you the problems. If the pattern is working against you, then I would change the pattern. By making a commit the default behaviour of the using block, you are assuming that every use of a database results in a commit, which clearly is not the case - especially if an error occurs. An explicit commit, possibly combined with a try/catch block would work better.

However, if you really want to keep your use of the pattern as is, you can use:

bool isInException = Marshal.GetExceptionPointers() != IntPtr.Zero
                        || Marshal.GetExceptionCode() != 0;

in your Displose implementation to determine if an exception has been thrown (more details here).

这篇关于使用块从异常中检测到Dispose()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆