2011-03-24 65 views
4

我正在處理一個程序中的問題。它由2個DLL組成,其中dll引用的是dll B.Dll A包含一個公共方法,其中第一個動作(在實例化B中的任何類之前)將檢查某個網絡位置以查看新版本的dll B是否可用。如果是這樣,它會將它下載到當前B的相同位置,這不應該成爲一個問題,因爲B中沒有任何內容會被實例化。可悲的是,它是實例化的,所以我得到一個錯誤,它已被擁有A的進程引用,並且不能被替換。如何防止在.NET中智能加載DLL?

您是否瞭解它已被引用的原因,以及是否有解決方案來避免此問題?

public class L10nReports//Class in DLL A 
{ 
    public L10nReports() //constructor 
    { 
    } 

    //only public method is this class 
    public string Supervise(object projectGroup, out string msg) 
    { 
     //Checks for updates of dll B and downloads it if available. And fails. 
     manageUpdate(); 

     //first instanciation of any class from dll B 
     ReportEngine.ReportEngine engine = new ReportEngine.ReportEngine(); 

     string result = engine.Supervise(projectGroup, out msg); 

     return result; 
    } 

回答

5

Jit編譯器需要加載Dll B,以檢查/驗證Supervise方法。

將呼叫轉移到Dll到另一種方法,和prevent this method from being inlined[MethodImpl(MethodImplOptions.NoInlining)])。否則,你可能會有奇怪的效果從調試模式切換到發佈模式。

如果我沒有記錯,內聯函數不會用於調試編譯的代碼,但是釋放代碼可能會內聯被調用的方法,從而使Jitter在檢查之前加載Dll B.

//only public method is this class 
    // all calls to dll B must go in helper function 
    public string Supervise(object projectGroup, out string msg) 
    { 
     //Checks for updates of dll B and downloads it if available. And fails. 
     manageUpdate(); 

     return SuperviseHelper(projectGroup, out msg); 
    } 

    [MethodImpl(MethodImplOptions.NoInlining)] 
    public string SuperviseHelper(object projectGroup, out string msg) { 
     //first instanciation of any class from dll B 
     ReportEngine.ReportEngine engine = new ReportEngine.ReportEngine(); 

     string result = engine.Supervise(projectGroup, out msg); 

     return result; 
    } 
+2

好的電話沒有內聯 – 2011-03-24 16:04:49

+1

猜猜我是怎麼找到的?它仍然很痛。 – GvS 2011-03-24 16:07:19

+0

我把類實例化的另一種方法(請參閱我的評論在菲利普里克的答案),但這是行不通的。添加非內聯屬性不會改變,我仍然得到相同的錯誤,dll被引用。 – Antoine 2011-03-24 16:31:18

6

當你的「Supervise」方法被打開時,B dll將被加載。這裏的問題是DLL第一次加載類型信息某些類型需要B.dll,而不是第一次對象被實例化。

因此,在引用B.dll中的任何類型之前以及在調用任何使用B.dll中的類型的方法之前,您必須檢查更新。

public class L10nReports//Class in DLL A 
{ 
    public L10nReports() //constructor 
    { 
    } 


    //only public method is this class 
    public string Supervise(object projectGroup, out string msg) 
    { 
     manageUpdate(); 
     return SuperviseImpl(projectGroup, out msg); 
    } 


    private string SuperviseImpl(object projectGroup, out string msg) 
    { 
     //first instanciation of any class from dll B 
     ReportEngine.ReportEngine engine = new ReportEngine.ReportEngine(); 

     string result = engine.Supervise(projectGroup, out msg); 

     return result; 
    }