從 .NET Framework 4.6 開始,執行階段包含用於即時編譯的新 64 位 JIT 編譯器。 這項變更不會影響使用32位 JIT 編譯程式的編譯。
非預期的行為或例外狀況
在某些情況下,使用新的 64 位 JIT 編譯程式進行編譯會導致運行時間例外狀況,或執行舊版 64 位 JIT 編譯程式所編譯的程式代碼時,不會觀察到的行為。 下列是已知的差異︰
這很重要
所有這些已知問題都已在使用 .NET Framework 4.6.2 發行的新 64 位編譯程式中解決。 大部分也已在 Windows Update 隨附的 .NET Framework 4.6 和 4.6.1 服務版本中解決。 您可以藉由確保您的 Windows 版本是最新的,或升級至 .NET Framework 4.6.2,來消除這些問題。
在某些情況下,已開啟最佳化的發行組建中的 Unboxing 作業可能會擲回 NullReferenceException。
在某些情況下,執行大型方法主體中的實際執行程式碼可能會擲回 StackOverflowException。
在特定情況下,傳遞至方法的結構會被視為參考型別,而不是 Release 組建中的實值型別。 這個問題的其中一種表現,就是集合中的個別項目會以非預期的順序出現。
在某些情況下,如果啟用最佳化,UInt16 的值在設定高位元時的比較會不正確。
在某些情況下,尤其是初始化陣列值時,使用 OpCodes.Initblk IL 指令初始化記憶體,可能會以不正確的值初始化記憶體。 這會造成未處理的例外狀況或不正確的輸出。
在少數情況下,如果啟用編譯器最佳化,條件式位元測試可能會傳回不正確的 Boolean 值或擲回例外狀況。
某些狀況下,如果使用
if陳述式在進入try區塊之前和自try區塊退出時測試某項條件,而且也在catch或finally區塊中評估該條件時,新版 64 位元 JIT 編譯器在最佳化程式碼時會將if條件自catch或finally區塊中移除。 因此,if或catch區塊的finally陳述式中的程式碼會無條件執行。
已知問題的緩解措施
如果您遇到上述問題,可以採取以下任一種方式來解決︰
升級至 .NET Framework 4.6.2。 隨附於 .NET Framework 4.6.2 中的新版 64 位元編譯器可以解決這些已知問題。
執行 Windows Update,確定您的 Windows 已更新至最新版本。 .NET Framework 4.6 和 4.6.1 的服務更新可解決上述問題中除了 Unboxing 作業之 NullReferenceException 以外的所有問題。
使用舊版 64 位元 JIT 編譯器編譯。 如需如何進行的詳細資訊,請參閱降低其他問題的風險一節。
緩和其他問題
如果舊版和新版 64 位元 JIT 編譯器編譯的程式碼之間有任何差異,或是使用新版 64 位元 JIT 編譯器編譯的應用程式偵錯版本和發行版本之間有任何差異,您可以使用舊版 64 位元 JIT 編譯器搭配下列方式來編譯應用程式:
根據每個應用程式,您可以在應用程式的組態檔中新增 useLegacyJit 元素。 下列程式碼會停止以新版 64 位元 JIT 編譯器進行編譯,改用舊版 64 位元 JIT 編譯器。
<?xml version ="1.0"?> <configuration> <runtime> <useLegacyJit enabled="1" /> </runtime> </configuration>若以每一使用者為基礎,您可以將名為
REG_DWORD的useLegacyJit值加入至登錄的HKEY_CURRENT_USER\SOFTWARE\Microsoft\.NETFramework索引鍵。 值為 1 會啟用舊版 64 位元 JIT 編譯器;值為 0 會停用它,並啟用新版 64 位元 JIT 編譯器。若以每一電腦為基礎,您可以將名為
REG_DWORD的useLegacyJit值加入至登錄的HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework索引鍵。 值為 1 會啟用舊版 64 位元 JIT 編譯器;值為 0 會停用它,並啟用新版 64 位元 JIT 編譯器。
您也可以前往 Microsoft Connect 回報錯誤,讓我們知道問題所在。