2011-06-22 71 views
0

在.NET 3.5和更低的,以下(略粗例如)工作得很好:如何可靠地確定在.NET調用組件4.0

組件A:

public static class ClassInAssemblyA 
{ 
    public static string GetCallingAssemblyLocation() 
    { 
     return System.Reflection.Assembly.GetCallingAssembly().GetName(false).CodeBase; 
    } 
} 

大會B:

public class ClassInAssemblyB 
{ 
    public string AssemblyName { get; private set; } 

    public ClassInAssemblyB() 
    { 
     AssemblyName = ClassInAssemblyA.GetCallingAssemblyLocation(); 
    } 
} 

大會C:

var assemblyName = new ClassInAssemblyB().AssemblyName; 
Assert.That(assemblyName.Contains("AssemblyB")); 

不幸的是,.NET 4.0 CLR似乎被優化爲將AssemblyA代碼內聯到AssemblyB,因此上述測試實際上在調試模式下執行時會通過,但在發佈模式中失敗。在逐步完成時再現錯誤基本上是不可能的。

停止內聯的一種方法是要求調用者每次參考AssemblyA時都添加屬性[MethodImpl(MethodImplOptions.NoInlining)]。這是一個需要調用者瞭解庫的內部工作的解決方案,它不應該是他們的問題,所以我不願意走這條路。

有沒有其他方法可以在運行時找出調用程序集文件名是什麼

+2

爲什麼你需要知道調用程序集? –

回答

1

我不認爲有任何解決方案,除了使用MethodImplOptions.NoInlining。請參閱GetCallingAssembly的文檔,其中幾乎包含了這種確切的場景。另外,請注意,您需要將屬性添加到兩個 A中的方法和B中的方法,因爲內聯到其調用程序集中會導致您看到的行爲。

0

我的理解是,在您嘗試測試自遞歸調用的情況下,JIT編譯器將始終尊重[Flags(MethodImplOptions.NoInlining)],但可能爲

這是基於

  1. MethodImplOptions的文檔(這似乎調出尾遞歸作爲一個特例)
  2. 的CLI規格的報價在這裏討論:

http://bytes.com/topic/c-sharp/answers/509557-race-conditions-c-eventing

(根據我的閱讀,它沒有討論尾遞歸)

相關問題