2013-03-22 8 views
35

निम्न अपवाद का कारण क्या हो सकता है?सिस्टम। MissingMethodException Int32 सिस्टम। पर्यावरण। get_CurrentManagedThreadId()

System.MissingMethodException Int32 System.Environment.get_CurrentManagedThreadId() 

इस विधि कॉल IEnumerable<> उपज तरीकों के लिए सी # संकलक द्वारा उत्पन्न किया जा रहा है।

.NET Framework v4.0 x86 स्थापित है और बाइनरी v4.0 किसी भी CPU के लिए संकलित है।

+1

यह "विधि नहीं मिला:' Int32.System "के रूप में भी पॉप अप करता है।Environment.get_CurrentManagedThreadId() '। – EBarr

उत्तर

52

CurrentManagedThreadId एक .NET 4.5 संपत्ति है, इसलिए आपको कोड चलाने के लिए 4.5 की आवश्यकता होगी। इस समस्या के बारे में विश्लेषण के लिए Iterator blocks, missing methods, and .NET 4.5 देखें।

संक्षेप में:

आप अपने आवेदन का निर्माण तो स्थापित .NET 4.5 के साथ एक सिस्टम पर (.NET 4.0 पर लक्षित), यह संकलन के लिए आधार के रूप में 4.5 का उपयोग करेगा, क्योंकि .NET 4.0 फ़्रेमवर्क हमेशा .NET 4.5 द्वारा अधिलेखित किया जाता है।

यदि आपका एप्लिकेशन yield return का भी उपयोग करता है, तो यह केवल 4.0 स्थापित सिस्टम पर असफल हो जाएगा क्योंकि 4.5 फ्रेमवर्क के लिए संकलित किए जाने पर इस कथन के कार्यान्वयन को एक नई संपत्ति का उपयोग किया जाता है।

इसे हल करने के लिए, सुनिश्चित करें कि आपके कंपाइलर सिस्टम में 4.0 संदर्भ असेंबली हैं।

+0

मैं हाल ही में इस समस्या को देख रहा हूं और देखा है कि 4.6.1 के साथ एक बिल्ड सर्वर ने 'Thread.CurrentThread.ManagedThreadId' पर आधारित कोड बनाया है। मैं इसे कहीं भी ऑनलाइन दस्तावेज नहीं ढूंढ पाया है, लेकिन इससे पता चलता है कि एमएस ने बाद में संस्करणों में इस समस्या को ठीक किया है। – Iain

3

सेकेंडिंग फ़्लेल का उत्तर; अधिक संदर्भ के लिए, यहां समस्या का एक संक्षिप्त विश्लेषण है:

जब संकलक IEnumerable लौटाते हुए एक इटरेटर ब्लॉक को संसाधित करता है, तो यह पुनरावृत्ति तर्क रखने के लिए एक निजी IEnumerable कक्षा उत्पन्न करता है।

.method private final hidebysig newslot virtual 
    instance class [mscorlib]System.Collections.Generic.IEnumerator`1<string> 'System.Collections.Generic.IEnumerable<System.String>.GetEnumerator'() cil managed 
{ 
    .custom instance void [mscorlib]System.Diagnostics.DebuggerHiddenAttribute::.ctor() = (
     01 00 00 00 
    ) 
    .override method instance class [mscorlib]System.Collections.Generic.IEnumerator`1<!0> class [mscorlib]System.Collections.Generic.IEnumerable`1<string>::GetEnumerator() 
    // Method begins at RVA 0x57848 
    // Code size 89 (0x59) 
    .maxstack 6 
    .locals init (
     [0] bool, 
     [1] class DOT.Core.MiscHelpers/'<ReadLines>d__0', 
     [2] class [mscorlib]System.Collections.Generic.IEnumerator`1<string> 
    ) 

    IL_0000: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread() 
    IL_0005: callvirt instance int32 [mscorlib]System.Threading.Thread::get_ManagedThreadId() 
    IL_000a: ldarg.0 
    IL_000b: ldfld int32 DOT.Core.MiscHelpers/'<ReadLines>d__0'::'<>l__initialThreadId' 
    IL_0010: bne.un IL_0027 

सूचना System.Threading.Thread::get_CurrentThread() और System.Threading.Thread::get_ManagedThreadId(); के लिए कॉल: यह आईएल की शुरुआत 4.0 संकलक द्वारा अपने GetEnumerator विधि के लिए उत्पन्न है। जनरेटेड विधि ऑप्टिमाइज़ेशन करने के लिए इसका उपयोग करती है, जहां IEnumerable तुरंत उपभोग किया जाता है [1], वही ऑब्जेक्ट इंस्टेंस लौटाया जाता है (एक कन्स्ट्रक्टर कॉल की लागत को बचाता है)।

निम्नलिखित आईएल 4.5 संकलक द्वारा उत्पन्न होता है:

.method private final hidebysig newslot virtual 
    instance class [mscorlib]System.Collections.Generic.IEnumerator`1<string> 'System.Collections.Generic.IEnumerable<System.String>.GetEnumerator'() cil managed 
{ 
    .custom instance void [mscorlib]System.Diagnostics.DebuggerHiddenAttribute::.ctor() = (
     01 00 00 00 
    ) 
    .override method instance class [mscorlib]System.Collections.Generic.IEnumerator`1<!0> class [mscorlib]System.Collections.Generic.IEnumerable`1<string>::GetEnumerator() 
    // Method begins at RVA 0x4830c 
    // Code size 64 (0x40) 
    .maxstack 2 
    .locals init (
     [0] class DOT.Core.MiscHelpers/'<ReadLines>d__0' 
    ) 

    IL_0000: call int32 [mscorlib]System.Environment::get_CurrentManagedThreadId() 
    IL_0005: ldarg.0 
    IL_0006: ldfld int32 DOT.Core.MiscHelpers/'<ReadLines>d__0'::'<>l__initialThreadId' 
    IL_000b: bne.un IL_002b 

सूचना पिछले विधि से दो कॉल अब System.Environment::get_CurrentManagedThreadId() ने ले ली है, जो एक संपत्ति है .NET 4.5 में जोड़ा।

चूंकि 4.5 अपग्रेड 4.0 सी # कंपाइलर (csc.exe) को ओवरराइट करता है, इसलिए आपकी मशीन पर 4.0 के लिए संकलित कोड नए आईएल टेम्पलेट का उपयोग करेगा और वेनिला 4.0 इंस्टॉल पर नहीं चलाएगा, जब तक आपके पास .NET 4.0 संदर्भ न हो असेंबली [2], जो कंपाइलर को आईएल के पुराने संस्करण को उत्पन्न करने का कारण बनती है।

[1] पहली बार यह उस धागे पर खपत है जिसने इसे बनाया है (उदाहरण के लिए एक foreach स्टेटमेंट में)।

[2] .NET Framework इंस्टॉलर से .NET 4.0 कंपाइलर निकालना वास्तव में संभव है, और इसके साथ अपने कोड को संकलित करने के लिए अपनी प्रोजेक्ट फ़ाइलों को संशोधित करना संभव है। यह समस्या को हल करने का एक और तरीका हो सकता है, लेकिन यह एक लंबी कहानी है और मैं यहां विवरण में नहीं जाऊंगा

संबंधित मुद्दे