none
I am a little puzzled about the use of the ReliabilityContractAttribute .... RRS feed

  • Question

  • Hi Everybody

    I am a little puzzled about the use of the ReliabilityContractAttribute in relation to constrained execution regions (CERs). If it’s supposed to be used on methods that are called from within a CER, shouldn’t the parameters of the attribute describe how it behaves if it called from within a CER? For example this method:

          private int someField;
          private int someOtherField;
    
          public void SomeMethod()
          {
            someField = 1;
            someOtherField = 2;
          }
    

    If the method is called from within a CER, it should not fail? and the attribute for the method would be:

    [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]

    But the documentation indicates that the attribute for this method would be

    [ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]

    But why? If anybody knows about CERs I would like to hear about the usage of the ReliabilityContractAttribute

    Thanks

    Friday, June 18, 2010 5:22 AM

Answers

  • But it is to me, still not crystal clear if the ReliabilityContractAttribute describes the methods behavior when called from within a CER or if it describes what happens if it called from outside a CER.

     

    The ReliabilityContractAttribute describes what state corruption could potentially happen within that method as a result of asynchronous exceptions (whether under CER execution or not) and what guarantees the method makes for succeeding in spite of that (only under CER execution).

    For example, throwing a ThreadAbortException would not be a problem within a CER because that will delay the throw until the CER has been exited, but a given method could be allocating memory beyond what normal JIT compilation would allocate and potentially make that method susceptible to an out of memory exception. If this method is run within a CER, the CER is going to attempt to mitigate issues by allocating memory up front and early, but there's still a chance that something might still happen .

    In that case, you would need to check whether the effects of this would corrupt any particular state and mark it as such. Because the custom allocations are happening, you would have to mark it as Cer.MayFail as the best guarantee. You could potentially move that guarantee up to a level of Cer.Success if what you are doing can be handled (i.e. remove potential failure points in code, etc).

    • Marked as answer by Damkjer Monday, June 21, 2010 4:34 PM
    Friday, June 18, 2010 7:50 PM

All replies

  • Which documentation are you referring to?
    Friday, June 18, 2010 4:19 PM
  • Here

    http://msdn.microsoft.com/en-us/library/system.runtime.constrainedexecution.reliabilitycontractattribute.aspx

    It states that the attribute is used to indicate what happens "in the face of exceptional conditions" as if the method was not called from within a CER, but if the method is called from within a CER it will not encounter asynchronous exceptions.

    Here

    http://msdn.microsoft.com/en-us/library/system.runtime.constrainedexecution.cer.aspx

    It states about the Cer parameter for the attribute, that if I use Cer.Mayfail or Cer.Success I need to put a CER inside the method itself, as if the ReliabilityContractAttribute described what happens if the method was called from outside a CER. Yet in the remarks it states "The Cer enumeration specifies the behavior of a method, type, or assembly within a constrained execution region (CER)." in which case it will not encounter asynchronous exceptions (and a CER region inside the method would be unnecessary).

    The other consistency parameter:

    http://msdn.microsoft.com/en-us/library/system.runtime.constrainedexecution.consistency.aspx

    also states that it is used to indicate what happens "in the face of exceptional conditions" as if the ReliabilityContractAttribute describes what happens if it called outside a CER.

    Also the PrepareConstrainedRegions method:

    http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.runtimehelpers.prepareconstrainedregions.aspx

    here it says that methods called from inside a CER must be marked with a ReliabilityContractAttribute: "Code that is marked as a constrained region must only call other code with strong reliability contracts". Again here the attribute is stated to describe the behavior of a method when called from inside a CER and again putting CERs inside the method itself should not be necessary.

    I have read several articles about CERs, among others:

    - http://blogs.msdn.com/b/bclteam/archive/2005/06/14/429181.aspx

    - http://msdn.microsoft.com/en-us/magazine/cc163298.aspx

    - http://msdn.microsoft.com/en-us/library/ms228973.aspx

    - http://msdn.microsoft.com/en-us/magazine/dd419661.aspx

    - http://msdn.microsoft.com/en-us/library/ms228970(VS.85).aspx

    - http://www.codeproject.com/KB/dotnet/safehandle.aspx

    - http://msdn.microsoft.com/en-us/magazine/cc163716.aspx

    - http://www.bluebytesoftware.com/blog/PermaLink.aspx?guid=f9a1d4c8-553b-4cc1-b1d6-0a8c395d8e9c

    But it is to me, still not crystal clear if the ReliabilityContractAttribute describes the methods behavior when called from within a CER or if it describes what happens if it called from outside a CER.

    But if it describes what happens when it called from inside a CER, then asynchronous exceptions can be discarded as a reason for the method to fail and the method would always succeed and it should be marked with the reliability contract:

    [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]

    Right?

     

     

    Friday, June 18, 2010 5:13 PM
  • But it is to me, still not crystal clear if the ReliabilityContractAttribute describes the methods behavior when called from within a CER or if it describes what happens if it called from outside a CER.

     

    The ReliabilityContractAttribute describes what state corruption could potentially happen within that method as a result of asynchronous exceptions (whether under CER execution or not) and what guarantees the method makes for succeeding in spite of that (only under CER execution).

    For example, throwing a ThreadAbortException would not be a problem within a CER because that will delay the throw until the CER has been exited, but a given method could be allocating memory beyond what normal JIT compilation would allocate and potentially make that method susceptible to an out of memory exception. If this method is run within a CER, the CER is going to attempt to mitigate issues by allocating memory up front and early, but there's still a chance that something might still happen .

    In that case, you would need to check whether the effects of this would corrupt any particular state and mark it as such. Because the custom allocations are happening, you would have to mark it as Cer.MayFail as the best guarantee. You could potentially move that guarantee up to a level of Cer.Success if what you are doing can be handled (i.e. remove potential failure points in code, etc).

    • Marked as answer by Damkjer Monday, June 21, 2010 4:34 PM
    Friday, June 18, 2010 7:50 PM
  • OK, Thank you for a good answer. Let’s see if I got this right. The method as I described it above would probably be marked:

            [ReliabilityContract(Consistency.MayCorruptInstanceCer.MayFail)]

     But if I put a CER inside it:

            private int someField;
            private int someOtherField;
     
            public void SomeMethod()
            {
                RuntimeHelpers.PrepareConstrainedRegions();
                try { }
                finally
                {
                    someField = 1;
                    someOtherField = 2;
                }
            }

     

    I could mark it with:

            [ReliabilityContract(Consistency.WillNotCorruptStateCer.Success)] 

    Because:

    1.       I’m not allocating memory or using the stack in the CER of the method, so I know that the assignments will both execute, meaning no corruption. The something that might happen, has been resolved to the extent that I know that the assignments will either both execute or none of them, whether or not the method is called from inside a CER. This satisfies the Consistency.WillNotCorruptState part.

     

    2.       And when the method itself is called from inside a CER, an asynchronous exception would not be thrown either before or after the CER that I put inside the method, so I know that the method would succeed in its intended job. This satisfies the Cer.Success part.

    It's a simple example, but I don't wan't to complicate it to much.

    Thanks 

    Friday, June 18, 2010 9:50 PM
  • That's right. I think that the initial method (without the inner CER) would be marked [ReliabilityContract(Consistency.MayCorruptInstance, Cer.Success)] because we're dealing solely with a ThreadAbort situation as the corrupting factor and that is completely negated within a CER, but I agree that with the changes you've made it would be marked as WillNotCorruptState and Success, for the reasons you've mentioned.
    Monday, June 21, 2010 4:17 PM
  • Thank you :-)
    Monday, June 21, 2010 4:36 PM