2011-12-02 128 views
4

所有,如何正確多線程在C#在運行時調用一個DLL

我希望寫要使用的插件.dll文件/通過在運行時調用.NET應用程序調用。我的.dll是一個WinForm,並顯示正在進行的(計算上很昂貴的)操作。從主應用程序調用的.dll通過.NET System.Reflection調用。我必須向呼叫應用程序提供名稱空間,方法我想調用。

我想多線程我的.dll,以便它更友好,我只是真的很熟悉BackgroundWorker s。

編輯:擴展到問題。

因此,我調用該.dll如下:

if (classType != null) 
{ 
    if (bDllIsWinForm) 
    { 
     classInst = Activator.CreateInstance(classType); 
     Form dllWinForm = (Form)classInst; 
     dllWinForm.Show(); 

     // Invoke required method. 
     MethodInfo methodInfo = classType.GetMethod(strMethodName); 
     if (methodInfo != null) 
     { 
      object result = null; 
      // The method being called in this example is 'XmlExport'. 
      result = methodInfo.Invoke(classInst, new object[] { dllParams }); 
      return result.ToString(); 
     } 
    } 
    else 
    { 
     // Else not a WinForm do simalar. 
    } 
} 

所以後來在WinForm爲.dll我想多線程費力的工作,這樣我可以顯示正在發生的事情的時間。因此,在.dll文件,使用BackgroundWorker我:

BackgroundWorker bgWorker; // Global.  

public string XmlExport(object[] connectionString) 
{ 
    try 
    { 
     bgWorker = new BackgroundWorker { WorkerReportsProgress = true, WorkerSupportsCancellation = true }; 
     bgWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork); 
     bgWorker.ProgressChanged += new ProgressChangedEventHandler(bgWorker_ProgressChanged); 
     bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorker_RunWorkerCompleted); 

     // Wait until workerThread is done. 
     threadDoneEvent = new AutoResetEvent(false); 
     bgWorker.RunWorkerAsync(); 
     threadDoneEvent.WaitOne(); 
     return strResult; // Global String strResult 
    } 
    catch (Exception) 
    { 
     throw; 
    } 
} 

然後我有DoWork事件處理程序:

void bgWorker_DoWork(object sender, DoWorkEventArgs e) 
{ 
    BackgroundWorker thisWorker = sender as BackgroundWorker; 
    strResult = (string)this.XmlExportBgw(ref thisWorker); // Or should I use bgWorker? 
    e.Result = strResult; 
} 

public string XmlExportThreaded(ref BackgroundWorker thisWorker) 
{ 
    try 
    { 
     // Some expesive work... 

     // UI. 
     InfoBall infoBall = new InfoBall(); // Class containing processing information. 
     // Set infoBall parameters here... 
     (thisWorker as BackgroundWorker).ReportProgress(infoBall.progressBarValue, infoBall); 

     // Some more expensive work... 

     // UI. 
     (thisWorker as BackgroundWorker).ReportProgress(infoBall.progressBarValue, infoBall); 
    } 
    //... 
} 

的`ProgressChanged」事件是

void bgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) 
{ 
    // UI. 
    InfoBall someBall = (InfoBall)e.UserState; 

    // Update process information. 
    if (someBall.showRichTextBox) 
    { 
     this.richTextBox.AppendText(someBall.richTextBoxText); 
     this.richTextBox.ScrollToCaret(); 
    } 
    return; 
} 

除以上代碼我有通常的RunWorkerCompleted等。

T他調用的應用程序已被編寫爲允許用戶在運行時調用.NET .dll。我試圖放在一起的.dll是一個時間密集型的,只會提供給特定用戶。我運行了上述代碼,問題是它不會正確更新用戶界面。那就是你不能操作(調整大小,點擊等)Form,它不會打印和處理信息,直到處理結束時纔會打印多次最終的消息。但是,它正確地生成我需要的.xml文件。我究竟做錯了什麼?我應該從一個單獨的線程調用.dll方法嗎?

任何幫助將不勝感激。非常感謝你花時間陪伴。

+1

刪除threadDoneEvent.WaitOne()調用。開始一個線程,然後等待它完全破壞了使用線程的原因。並阻止運行RunWorkerCompleted事件,這是您要用來處理線程結果的事件。 –

+0

直到.dll完成其工作後,我纔不想傳回調用應用程序。通過這種方式,線程完成了工作,而顯示.dll所做工作的WinForm仍處於打開狀態。主要問題是我的.dll的用戶界面不能正確更新?非常感謝你花時間陪伴。 – MoonKnight

+1

ProgessChanged事件也不會觸發。你不能等。 –

回答

4

我不確定你想要在該dll中執行哪種方法。我假設他們不是異步意味着你的主線程(應用程序)將停止,直到他們完成執行。一個簡單的例子可以用Messagebox.show(「myMessage」)來演示;方法。例如,你怎麼能一次執行3個消息框?沒有使用多個線程將不可能。希望這有助於方法:

public void SomeMethod() 
    { 


     Thread thread = new Thread(new ThreadStart(() => 
     { 
      // this code is going to be executed in a separate thread 
      MessageBox.Show("hello");  

      // place additional code that you need to be executed on a separate thread in here    

     })); 

     thread.Start(); 
    } 

那麼,如果我調用該方法的3倍:

enter image description here

我現在將運行在我的程序4個線程。主線程加上我創建的3個調用。

+0

非常感謝,這讓我想起使用線程這種方式!但我無法以這種方式啓動.dll,因爲我無法訪問調用應用程序源代碼 - 我只能傳遞命名空間和類&方法。但是,假設我的.dll中的WinForm類是你的'MessageBoxes'中的一個,我想用更新信息更新這個消息框,這意味着我想要多線程我的方法來完成所有的工作,但是提供信息給用戶通過表單。我正在考慮使用*基於事件的異步模式*?非常感謝您的回答。 – MoonKnight

相關問題