ठीक है, मैं नहीं जानता कि यदि यह एक बग या सिर्फ एक वास्तव में अजीब किनारे मामला है जिसमें CERs को संभालने के लिए तैयार किया गया है नहीं कर रहे थे।
तो यहां प्रासंगिक कोड है।
private static IEnumerable<int> Iterate()
{
RuntimeHelpers.PrepareConstrainedRegions();
try { cerWorked = false; yield return 5; }
finally { StackOverflow(); }
}
इस संकलित जाता है और हमें परावर्तक हम इस मिल के साथ सी # में डिकंपाइल करने का प्रयास करते हैं।
private static IEnumerable<int> Iterate()
{
RuntimeHelpers.PrepareConstrainedRegions();
cerWorked = false;
yield return 5;
}
अब बस एक सेकंड प्रतीक्षा करें! परावर्तक यह सब खराब हो गया है। यह वास्तव में आईएल जैसा दिखता है।
.method private hidebysig static class [mscorlib]System.Collections.Generic.IEnumerable`1<int32> Iterate() cil managed
{
.maxstack 2
.locals init (
[0] class Sandbox.Program/<Iterate>d__1 d__,
[1] class [mscorlib]System.Collections.Generic.IEnumerable`1<int32> enumerable)
L_0000: ldc.i4.s -2
L_0002: newobj instance void Sandbox.Program/<Iterate>d__1::.ctor(int32)
L_0007: stloc.0
L_0008: ldloc.0
L_0009: stloc.1
L_000a: br.s L_000c
L_000c: ldloc.1
L_000d: ret
}
है ध्यान दें कि, वास्तव में, क्या परावर्तक कहते हैं के बावजूद PrepareConstrainedRegions
करने के लिए कोई कॉल। तो यह कहां छिप रहा है? खैर, यह ऑटो उत्पन्न IEnumerator
की MoveNext
विधि में ठीक है। इस बार परावर्तक इसे सही बनाता है।
private bool MoveNext()
{
try
{
switch (this.<>1__state)
{
case 0:
this.<>1__state = -1;
RuntimeHelpers.PrepareConstrainedRegions();
this.<>1__state = 1;
Program.cerWorked = false;
this.<>2__current = 5;
this.<>1__state = 2;
return true;
case 2:
this.<>1__state = 1;
this.<>m__Finally2();
break;
}
return false;
}
fault
{
this.System.IDisposable.Dispose();
}
}
और यह कहां StackOverflow
पर रहस्यमय तरीके से स्थानांतरित हुआ? m_Finally2()
विधि के अंदर।
private void <>m__Finally2()
{
this.<>1__state = -1;
Program.StackOverflow();
}
तो एक छोटे से अधिक बारीकी से इस परीक्षण कर सकते हैं। अब हमारे पास PrepareConstainedRegions
के बाहर try
ब्लॉक के अंदर कॉल है जहां यह होना चाहिए। और हमारे StackOverflow
कॉल finally
ब्लॉक से try
ब्लॉक पर स्थानांतरित हो गया है।
documentationPrepareConstrainedRegions
के अनुसार try
ब्लॉक से तत्काल पहले होना चाहिए। तो धारणा यह है कि अगर कहीं और रखा गया तो यह अप्रभावी है।
लेकिन, अगर सी # कंपाइलर को वह हिस्सा मिला तो भी सही चीजें खराब हो जाएंगी क्योंकि try
ब्लॉक बाधित नहीं हैं। केवल catch
, finally
, और fault
ब्लॉक हैं। और अंदाज लगाइये क्या? StackOverflow
कॉल finally
ब्लॉक से try
ब्लॉक पर ले जाया गया है!
इसके लिए आपको यह देखने के लिए पहला व्यक्ति क्या लगता है ... कम से कम जहां तक मैं इसके अन्य संदर्भों के लिए गुगलिंग से कह सकता हूं। –
मुझे यह https://vmccontroller.svn.codeplex.com/svn/VmcController/VmcServices/DetectOpenFiles.cs कोड का स्निपेट मिला जिसमें अनसुलझा लेखक सीईआर नहीं प्राप्त कर रहा है जिसे वह सोचता है कि वह हो रहा है। –
@ ब्रायन: लॉल, अच्छा। मुझे लगता है कि ऐसा कुछ ऐसा होता है जो अधिकतर लोग अक्सर उपयोग नहीं करते हैं, और जो लोग शायद पहले से ही इसके बारे में सोचा बिना सहजता से जानते हैं। बस मेरा अनुमान है, यद्यपि। – Mehrdad