2010-11-02 93 views
2

我試圖預加載組件在後臺線程,似乎當PreLoadAssemblies函數被調用沒有發生而像線程是死或某事(但我確實看到螺紋螺紋列表)。當我在單線程環境下運行代碼時,它工作正常。的BackgroundWorker不會被調用

這裏就是我創建背景呼叫:

BackgroundWorker backgroundWorker = new BackgroundWorker(); 
//[Threaded] 
private void InitlaizePoint() 
{ 
    backgroundWorker.DoWork += new DoWorkEventHandler(BackgroundInitalization); 
    backgroundWorker.RunWorkerAsync();   
} 

這裏是後臺初始化函數。它停下來(意思是什麼都沒有發生,我試着介紹PReLoadAssemblies後,我看到我的對話窗口進度條在「空」運行)。

private void BackgroundInitalization(object sender, DoWorkEventArgs e) 
{  
    try 
    { 
     PreLoadAssemblies(); 
    } 
    catch(Exception ex) 
    { 
     Console.WriteLine(ex.ToString()); 
    } 
} 

這裏是preloadassemblies的樣子:

private static void PreLoadAssemblies() 
{ 
    //statusController.PublishStatus("pre-loading assemblies"); 
    var missingAssemblies = new ArrayList(); 
    var loadedAssemblies = new ArrayList(); 
    LoadDependencies(Assembly.GetExecutingAssembly().GetName(), missingAssemblies, loadedAssemblies); 
} 

private static void LoadDependencies(AssemblyName name, ArrayList missingAssemblies, ArrayList loadedAssemblies) 
{ 
    try 
    { 
     //statusController.PublishStatus("Loading dependencies"); 

     Assembly a = Assembly.Load(name); 
     loadedAssemblies.Add(name.FullName); 
     foreach (AssemblyName depends in a.GetReferencedAssemblies()) 
     { 
      if (!IsAssemblyLoaded(depends.FullName, loadedAssemblies)) 
       LoadDependencies(depends, missingAssemblies, loadedAssemblies); 
     } 
    } 
    catch (Exception) 
    { 
     missingAssemblies.Add(name); 
    } 
} 

private static bool IsAssemblyLoaded(String name, ArrayList preloadedAssemblies) 
{ 
    if (preloadedAssemblies.IndexOf(name) == -1) 
     return false; 
    return true; 
} 

讓我知道如果你有任何想法。

謝謝

+1

什麼是PreLoadAssemblies方法? – SLaks 2010-11-02 15:02:07

+1

有兩個問題:您是否檢查過InitlaizePoint方法是否曾被調用過?您是否在DoWork方法的try線上放置了斷點以確保DoWork方法完全被調用?設置本身看起來不錯。 – 2010-11-02 15:03:06

+0

預加載組裝基本上是將所有引用的組件加載到內存中。 – 2010-11-02 15:24:49

回答

3

你究竟在哪裏調用這個方法? BackgroundWorker類需要消息泵已經運行,並且如果您在應用程序中(Application.Run()之前)過早調用該消息泵,將無法工作。

如果從這樣的事情是運行啓動畫面做這個主應用程序開始前,不幸的是,你需要做你自己的線程,而不是使用的BackgroundWorker的。注意:正如Henk Holterman指出的那樣,如果您沒有的消息泵(因爲您有一個控制檯應用程序而不是Winforms或WPF),那麼BackgroundWorker在您的應用程序中完全不起作用。

+0

是的,我確實從主應用程序啓動之前運行的啓動畫面調用它,但爲什麼後臺工作人員無法工作?即使當我使用自己的線程時,它也不起作用。 – 2010-11-02 15:26:37

+0

我很難找到我讀的地方,但BackgroundWorker專門設計用於從UI線程(即WinForms應用程序)中使用。我想它使用消息循環來將其事件傳遞給UI線程。所以在Application.Run()之前,它可能會被創建,但永遠不會被啓動。使用System.Threading.Thread而不是BackgroundWorker可能是最好的選擇。 – 2010-11-02 15:58:54

1

我們正在查看您的代碼的編輯版本。您刪除了造成死鎖的位。一些注意事項:

  • 您提到了「狀態進度欄」,但您的代碼沒有顯示任何證據。獲取更新欄提供了充足的死鎖方式。
  • 對PublishStatus的評論性調用是紅旗
  • 即使您需要關閉啓動畫面,也沒有RunWorkerCompleted事件處理程序的證據。當BGW上的主線程阻塞並且不會泵送消息時,BGW會發生死鎖
  • 組件之間存在循環依賴關係的轉角情況。您的代碼將無限循環地掛起。使用Build + Clean,Build + Build進行診斷。
  • 遠程,但幾個.NET程序集以及C++/CLI程序集都有一個模塊初始化程序。當程序集加載到非STA工作線程時,它可能不一定正常工作。

RunWorkerCompleted是我最好的猜測,直到您顯示未經編輯的代碼版本。