I was playing around with Constrained Execution Regions tonight to better round out my understanding of the finer details. I have used them on occasion before, but in those
I think I at least have a theory as to what is going on. If the while
loop is changed to put the thread into an alertable state then the ThreadAbortException
is injected even with a CER setup.
RuntimeHelpers.PrepareConstrainedRegions();
try
{
// Standard abort injections are delayed here.
Thread.Sleep(1000); // ThreadAbortException can be injected here.
// Standard abort injections are delayed here.
}
finally
{
// CER code goes here.
// Most abort injections are delayed including those forced by the CLR host.
}
So PrepareConstrainedRegions
will demote aborts issued from Thread.Abort
while inside the try
block so that it behaves more like Thread.Interrupt
. It should be easy to see why this would make the code inside try
a little safer. The abort is delayed until a point is reached where data structures are more likely to be in a consistent state. Of course, this assumes that a developer does not intentionally (or unintentionally for that matter) put the thread into an alertable state in the middle of updating a critical data structure.
So basically PrepareConstrainedRegions
has the added undocumented feature of further constraining when aborts will get injected while inside a try
. Since this feature is not documented it is prudent for developers to avoid relying on this assumption by not putting critical code in the try
block of a CER construct. As documented only the catch
, finally
, and fault
(not in C#) blocks are formally defined as the scoping of a CER.