C# 了解本例中CER的目的
我正在通读,试图理解受约束的执行区域,但在理解以下示例时遇到一些问题:C# 了解本例中CER的目的,c#,list,cer,C#,List,Cer,我正在通读,试图理解受约束的执行区域,但在理解以下示例时遇到一些问题: RuntimeHelpers.PrepareConstrainedRegions(); try { // Prepare my backout code MethodInfo m = _list.GetType().GetMethod("RemoveAt", new Type[] { typeof(int) }); RuntimeHelpers.PrepareMethod(m.MethodHandle
RuntimeHelpers.PrepareConstrainedRegions();
try {
// Prepare my backout code
MethodInfo m = _list.GetType().GetMethod("RemoveAt", new Type[] { typeof(int) });
RuntimeHelpers.PrepareMethod(m.MethodHandle);
IEnumerator en = c.GetEnumerator();
while(en.MoveNext()) {
_list.Insert(index++, en.Current);
// Assuming that these lines aren't reordered.
numAdded++;
}
_version++;
}
catch(Exception) {
// Reliable backout code
while(numAdded > 0) {
_list.RemoveAt(index--);
numAdded--;
}
throw;
}
我的理解是try
块是不受约束的,只有finally和catch块受约束。这意味着在try
块期间,可以随时抛出异步异常(例如ThreadAbortException),特别是可以在numAdded++
之前但在\u list.Insert之后抛出。在这种情况下,回退代码将从\u列表中删除太少的一项
鉴于此,我很难理解本例中受约束执行区域的用途
我对这一点的理解是正确的还是遗漏了什么?根据我的观察,CER的文件和实际行为并不完全相符。您描述的ThreadAbortException
在Insert
和numAdded++
之间被注入的问题在我测试过的任何.NET Framework版本中都不可能出现。这可能有两个原因
PrepareConstrainedRegions
对try
块有明显的影响,不管文档怎么说。它将延迟某些中止注射;特别是那些在线程处于可警报状态时未出现的线程
- 即使在没有
PrepareConstrainedRegions
调用的情况下,中止仍然不会被注入到该位置。根据SSCLI代码,将在向后跳转时注入中止,以在
循环时旋转
我在回答自己的相关问题,然后试图回答一个关于Thread.Abort
如何实际工作的问题时,发现了其中的一些问题
第二点是不合法的。这是SSCLI的一个实现细节,可能不会遗留到官方发行版中(尽管我怀疑它确实存在)。此外,它忽略了在执行Insert
期间在某个点注入中止的可能性。我想,Insert
的关键部分可能会在内部使用CER
第#1点可能很重要,但这引出了一个问题:为什么微软没有记录它,为什么你引用的文章也没有提到它。这篇文章的作者肯定知道这个事实。否则,我也不理解呈现的代码如何可能是安全的。换言之,目前看来只有在偶然的情况下才是安全的
如果我不得不猜测PrepareConstrainedRegions
在幕后做了什么,我会说它在JIT引擎中设置了一个标志,告诉它不要注入GC轮询钩子,该钩子策略性地放置在CERtry
块中向后分支跳转的代码中。这个GC轮询钩子是异步中止通常被注入的地方(除了它与垃圾收集相关的主要用途之外) 看起来这里肯定有问题。