以下异常可能是由什么引起的?
System.MissingMethodException Int32 System.Environment.get_CurrentManagedThreadId()
这个方法调用似乎是由C#编译器为生成返回类型为IEnumerable<>
的方法而生成的。
.NET Framework v4.0 x86已安装,二进制文件编译为v4.0 Any CPU。
CurrentManagedThreadId
是 .NET 4.5 的一个属性,所以你需要安装 4.5 才能运行代码。
有关此问题可能出现的分析,请参见迭代器块,缺少方法和.NET 4.5。
简而言之:
如果你在安装了 .NET 4.5 的系统上构建面向 .NET 4.0 的应用程序,它将使用 4.5 作为编译的基础,因为 .NET 4.0 Framework 总是被 .NET 4.5 覆盖。
如果你的应用程序还使用了 yield return
,它将在仅安装了 4.0 的系统上失败,因为编译此语句的实现使用了一个新属性,只有当编译为 4.5 Framework 时才可用。
要解决这个问题,请确保编译器系统具有 4.0 引用程序集。
Thread.CurrentThread.ManagedThreadId
的代码。我无法在网上找到相关文档记录,但这表明微软已经在后续版本中修复了这个问题。 - Iain支持 floele 的回答;为了更好的理解,这里简要分析一下问题:
当编译器处理返回一个 IEnumerable
的迭代器块时,它会生成一个私有的 IEnumerable
类来保存迭代逻辑。以下是 4.0 编译器为其 GetEnumerator
方法生成的 IL 的开头:
.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();
的调用。生成的方法使用这些来执行一个优化,即如果立即使用了 IEnumerable
[1],则返回相同的对象实例(节省构造函数调用的成本)。.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中添加的属性。请检查您的NuGet包,确保所有项目都使用相同版本的DLL。
Int32.System.Environment.get_CurrentManagedThreadId()
"。 - EBarr