2016-12-23 50 views
0

當我開發多個較小的應用程序時,我注意到我可以在這裏或那裏使用新的線程進行後臺任務。我已經嘗試了幾個選項,主要是後臺工作人員和代表。我想要做的是有一個專用的線程類來運行我的所有線程,我可以在多個程序中重用。創建一個類來處理線程

我正在尋找有關在這種情況下閱讀或查看或應該做什麼的指導。我現在該怎麼失敗

例子:

主線程(GUI)開始 用戶點擊按鈕1,它通過一些邏輯進入和啓動多個任務密集型計算(這將凍結GUI直到計算完成)。

我希望做的是看成是這樣的..

主線程(GUI)開始 用戶點擊按鈕1創建將在排隊的某種 GUI線程的報告清單作爲線程過程進度線程計算 線程在 (可能?)線程完成和出隊稍後有線程類循環在後臺等待項目排隊和處理,因爲它走了。

我的小任務,典型的方法是

Thread fooThread= new Thread((ThreadStart)delegate 
    { 
     //command 
    }); 

    fooThread.Start(); 

問題是,我的按鈕事件有更多的項目在他們(也許我應該重構呢?)

樣品

private void btnCopy_Click(object sender, EventArgs e) 
{ 
    //check file exists, check destination exists, etc 
    //start new thread 

    Thread fooThread= new Thread((ThreadStart)delegate 
    { 
     //copy files to destination using method foobarCopy(params) 
    }); 

    fooThread.Start(); 

//if file copy is successful, inform user on GUI. 
} 

我我主要使用.NET2.0,但根據需要可能會達到4.5。

+0

您按鈕點擊中的代碼應該可能是您的班級。 'FileCopier'或任何帶有'Start()'的。確定它是否已完成並且通知取決於您,但這真的是您的課程。我不確定你需要創建自己的線程管理器類,而是將該代碼重構爲業務對象,並且從那裏你至少可以看到下一個重構的基類中可以做些什麼。 – TyCobb

+2

聽起來像使用現有的線程池支持會更好。 –

+0

也許您應該使用異步回調方法來處理gui的結果,或者您可以使用面向方面的框架檢查或控制您的邏輯,數據等,如spring.net aop。 – FreeMan

回答

0

升級你的應用程序到.Net 4.5,你會放心。您將能夠利用任務和任務並行庫(TPL)基礎結構和await異步構造。

在當今的.Net時代,你必須有真正令人信服的理由,你爲什麼要手動創建自己的線程,而不是利用現有的線程池。一個這樣的原因可能是,如果你尋求它們在你的過程中得到新創建的線程的絕對控制被提到,但以下的原因不限於:

  • 當應該得到創建我的線程?
  • 應該在我的過程中創建多少個新線程?
  • 當我的線程應該被丟棄?
  • 從OS調度算法的立場來看,新線程的優先級應該是多少?例如高,中,低
  • 我的線程應該是後臺線程還是前臺線程?

對於典型的業務線應用程序,您幾乎不需要對線程進行如此多的精細控制。

所以,任務是你最好的朋友,可以幫助你擺脫凍結的用戶界面問題。你可以看我的博客here瞭解更多詳情。以下是我將如何重寫您的代碼:

private async void btnCopy_Click(object sender, EventArgs e) 
{ 
    //check file exists, check destination exists, etc 
    string sourceFile = @"C:\a.txt", destinationFile = @"C:\b.txt"; 
    //Let TPL do the heavy lifting of interacting with disk for I/O 
    var copyTask = await CopyFile(sourceFile, destinationFile); 

    /* 
    //Manual thread instantiation not needed. Hence commented 
    Thread fooThread = new Thread((ThreadStart)delegate 
    { 
     //copy files to destination using method foobarCopy(params) 
    }); 

    fooThread.Start(); 
    */ 

    //if file copy is successful, inform user on GUI. 
    if (copyTask) 
    { 
     //show a message box 
    } 
} 

private async Task<bool> CopyFile(string sourceFile, string destinationFile) 
{ 
    bool fileCopiedSuccessfully = true; 
    //here use async I/O methods from stream class which support the notion of tasks 
    try 
    { 
     using (FileStream sourceStream = File.Open(sourceFile, FileMode.Open)) 
     { 
      using (FileStream destinationStream = File.Create(destinationFile)) 
      { 
       //exactly at this point of time when the actual copy happens your GUI thread is completely 
       //free to do anything. It won't freeze. 
       //This work happens on a thread-pool thread which you don't have to worry about. 
       await sourceStream.CopyToAsync(destinationStream); 
      } 
     } 
    } 
    catch (IOException ioex) 
    { 
     fileCopiedSuccessfully = false; 
     MessageBox.Show("An IOException occured during copy, " + ioex.Message); 
    } 
    catch (Exception ex) 
    { 
     fileCopiedSuccessfully = false; 
     MessageBox.Show("An Exception occured during copy, " + ex.Message); 
    } 
    return fileCopiedSuccessfully ; 
} 
相關問題