2011-03-08 81 views
0

只有在使用該組件的特定類型時,才能加載通常引用的程序集。但這裏有一個問題:無論實際代碼(執行)路徑如何加載引用的程序集?

這是一個Winforms應用程序。儘管引用了PresentationFramework.dll & System.Xaml.dll程序集,但它們不應該被加載,因爲下面的代碼路徑從不執行;

bool useAutoHandler = false; 

if (useAutoHandler) // This is always false so below code is not executed! 
{ 
    var currentApplication = typeof(System.Windows.Application).GetProperty("Current"); 
    if (currentApplication != null) 
    { 
     var application = currentApplication.GetValue(this, null) as System.Windows.Application; 
     if (application != null) 
     { 
      application.DispatcherUnhandledException += this.DispatcherUnhandledException; 
     } 
    } 
} 

當我查詢與AppDomain.CurrentDomain.GetAssemblies(),我看到呈現框架芯被加載& XAML加載的程序集。有關爲什麼會出現這種情況的任何想法?

+0

那麼,你的代碼引用了System.Windows.Application,我相信它是在PresentationFramework.dll中找到的,它引用了PresentationCore.dll,所以我可以在代碼運行後立即看到這兩個程序集。我懷疑在你的代碼運行之前發生了很多事情,其中​​一些導致程序集加載。 – 2011-03-08 19:24:30

+0

System.Windows.Application來自PresentationFramework.dll,在編譯時必須知道,所以無論你做什麼(比如'if')它總是會被加載。如果你想動態加載程序集http://stackoverflow.com/questions/465488/c-load-assemblies-at-runtime – 2011-03-08 19:26:46

+0

是的,你是對的。代碼路徑並不重要,只要它們是靜態引用的,引用的程序集將被加載而不管實際用法。 – 2011-03-08 19:38:01

回答

2

您正在將PresentationFramework.dll程序集加載到此行:typeof(System.Windows.Application),因爲您正在靜態引用包含此程序集的類型。

如果您在發佈模式下編譯此版本,編譯器可能會優化此代碼並從生成的IL中完全刪除此if。如果if語句的主體是運行時結果IL的一部分,那麼執行包含此代碼的方法時,JIT將需要將其轉換爲機器代碼,並且因爲您在此程序集中靜態引用了一個類型它需要加載相應的程序集。

+0

那麼,代碼永遠不會執行,因爲它包含在塊'if(useAutoHandler){...}'useAutoHandler始終爲false! – 2011-03-08 19:18:55

+0

@Teoman Soygul,這沒關係。您正在使用此程序集靜態引用一個類,以便此程序集需要加載到AppDomain中,以便此代碼成功進行JIT。也許如果你在Release模式下編譯,編譯器會優化這段代碼,並完全刪除這個'if'的主體,並且程序集不會被加載。 – 2011-03-08 19:21:10

+0

那麼如果是這樣的話,即使沒有執行,使用程序集中的任何類型的任何代碼路徑都會導致程序集加載。我會稍後測試一下。 – 2011-03-08 19:24:12

3

引用的程序集正在加載到進程內存中,然後進入引用的方法。

如果你改變你的代碼是這樣的:

private void Foo() 
{ 
    var currentApplication = typeof(System.Windows.Application).GetProperty("Current"); 
    if (currentApplication != null) 
    { 
    var application = currentApplication.GetValue(this, null) as System.Windows.Application; 
    if (application != null) 
    { 
     application.DispatcherUnhandledException += this.DispatcherUnhandledException; 
    } 
    } 
} 

public void Bar(bool useAutoHandler) 
{ 
    if (useAutoHandler) 
    { 
    Foo(); 
    } 
} 

然後運行Bar(false)應該不會加載額外的組件。

相關問題