停止执行事件的方法

时间:2011-09-26 21:16:55

标签: .net events .net-1.1

我在一个类中有一个属性,当它被设置时,它将改变一些其他属性的值,其中任何一个都可能引发一个特定的回滚事件(比如RollbackEvent)。如果此类事件被触发,则原始属性所做的所有更改都已回滚,现在我需要该属性停止在其轨道上。

抛出异常不是一个选项(我认为)'因为会有另一个程序集消耗代码(实际上是另一个程序集在我的代码中捕获第二个事件,如果它无法处理情况,它命令我的代码回滚,并且在启动RollbackEvent的时候),不应该抛出任何异常。

更新

这是我的代码的一般概述,而AFAIK第二个程序集中的代码永远不会意识到在第一个程序中抛出异常,但是在“事务”之后回滚(显然)成功的代码就在第二个集会停止执行。

汇编1

public class Someclass
{
    public String SomeField
    {
        get { return this._someField; }
        set 
        {
            try 
            {
                this.BackupSomeFields();
                this._someField = value;
                //Some other Properties are changed
                //One of which may (and will for the purposes of the question) throw a DocumentRolledbackException exception
            }
            catch (DocumentRolledbackException ex)
            {
                return;
            }
        }
    }

    public String SomeOtherField
    {
        get { return this._someOtherField; }
        set 
        {
            this._someOtherField = value;
            //Raise AN event (handled in Assembly 2)
        }
    }


    public void RollbackProcessTransaction()
    {
        //Rollback changes with the backup created by the SomeField property

        //Raise THE event
        DocumentRolledBack(this, new EventArgs());
    }


    private void MyBase_DocumentRolledBack(Object sender, EventArgs e)
    {
        //This method is called when the DocumentRolledBack event is fired in the RollbackProcessTransaction method.
        throw new DocumentRolledbackException(this);
    }

}

大会2

public class SomeOtherClass
{
    private SomeClass obj;

    private HandleANEvent()
    {
        obj.RollbackProcessTransaction();
        //Code in this line on never gets executed! >.<
    }
}

基本上它一切正常,当在程序集1中抛出异常时,它会被属性捕获,然后这样的属性返回,但调用obj.RollbackProcessTransaction();之后的代码永远不会被执行...为什么?< / p>

PS 我在编辑器中编写了所有代码,因为我实际上是用VB编程的,所以不要把所有代码都放在那里,这只是为了让你理解。 / p>

2 个答案:

答案 0 :(得分:1)

喜欢这个吗?

public class Test
{               
    public object Foo1 
    {
        try
        {           
           Foo2 = 1;
           Foo3 = 2;
           Foo4 = 3;
        }
        catch (RollbackException ex) { }
    }

    private void DoRollback()
    {
       throw new RollbackException();
    }

    public object Foo2 { get; set; }
    public object Foo3 { get; set; }
    public object Foo4 { get; set; }

    private class RollbackException : Exception
    {
    }
}

编辑:

public class SomeOtherClass
{
    private SomeClass obj;

    public SomeOtherClass()
    {
      var backup = obj.Clone();
      try
      {
         obj.SomeField = "test";
      }
      catch (RollbackException ex)
      {
         obj = backup;
      }
    }
}

答案 1 :(得分:1)

最简单的方法是在更改之前记录每个属性的值,然后在发生错误时将其还原。如果每个属性都有一个快速退出,如果值设置相同,它将防止抛出进一步的异常。我从Magnus的回答中借了一点。

public class Test
{
    public object Foo1
    {
        object oldfoo2 = Foo2;
        object oldfoo3 = Foo3;
        object oldfoo4 = Foo4;
        try
        {
            Foo2 = 1;
            Foo3 = 2;
            Foo4 = 3;
        }
        catch (RollbackException ex) {
            Foo4 = oldfoo4;
            Foo3 = oldfoo3;
            Foo2 = oldfoo2;
        }
    }

    public object Foo2 {
        get {
            return foo2;
        }
        set {
            if (value == foo2) return;
            if (isInvalid(value)) throw new RollbackException();
            foo2 = value;
        }
    }
    private object foo2 = null;

    public object Foo3 { /* As Foo2 */ }
    public object Foo4 { /* As Foo2 */ }

    private class RollbackException : Exception
    {
    }
}