我一直在读书Pro Asynchronous Programming With .NET
,其中第一个代码示例演示了当涉及线程循环时,编译器在.NET 2.0 Framework上进行的优化。
代码如下:
class Program
{
static void Main(string[] args)
{
AsyncSygnal h = new AsyncSygnal();
while (!h.Terminate) ;
}
class AsyncSygnal
{
public bool Terminate;
public AsyncSygnal()
{
Thread monitorThread = new Thread(new ThreadStart(MonitorNetwork));
monitorThread.Start();
}
private void MonitorNetwork()
{
Thread.Sleep(3000);
Terminate = true;
}
}
}
在书中指出,release
构建上的JIT编译器将check移出while循环之外。对于debug
buid来说,它工作正常
这怎么可能?
用于调试的IL:
.method private hidebysig static void Main(string[] args) cil managed { .entrypoint // Code size 24 (0x18) .maxstack 2 .locals init ([0] class Program/AsyncSygnal h, [1] bool V_1) IL_0000: nop IL_0001: newobj instance void Program/AsyncSygnal::.ctor() IL_0006: stloc.0 IL_0007: br.s IL_000a IL_0009: nop IL_000a: ldloc.0 IL_000b: ldfld bool Program/AsyncSygnal::Terminate IL_0010: ldc.i4.0 IL_0011: ceq IL_0013: stloc.1 IL_0014: ldloc.1 IL_0015: brtrue.s IL_0009 IL_0017: ret } // end of method Program::Main
要发布的IL:
.method private hidebysig static void Main(string[] args) cil managed { .entrypoint // Code size 15 (0xf) .maxstack 1 .locals init ([0] class Program/AsyncSygnal h) IL_0000: newobj instance void Program/AsyncSygnal::.ctor() IL_0005: stloc.0 IL_0006: ldloc.0 IL_0007: ldfld bool Program/AsyncSygnal::Terminate IL_000c: brfalse.s IL_0006 IL_000e: ret } // end of method Program::Main
我想我真正要了解的是我试图了解所输出的IL。
[我一直在阅读Pro .NET异步编程,其中第一个代码示例演示了当线程为循环时,编译器在.NET 2.0 Framework上进行的优化...
让我们举个简单的例子: