close
以下根據 DKTD-WinFormThreading 文章節錄重點


1.

自己建立thread

優點: 精確管理thread生命週期

缺點: 執行緒數目過多時 ,CPU會耗費太多的資源處理Context Switching

2.

利用Threadpool

優點: 會依CPU 數或 CPU 核心數決定適當的 Thread 數處理排入Queue的工作

   1: ThreadPool.QueueUserWorkItem(new WaitCallback(Job), parameter);

缺點: 顯示結果需跨執行緒,所以需要使用到以下技能,包含delegate,invoke(同步)/beginInvoke(非同步)。

   1:  
   2:  
   3:  
   4: private void Job(object path)
   5: {
   6:    //重設統計數據 
   7:    fileCount = 0;
   8:    totalSize = 0;
   9:    //統計檔案數及大小 
  10:    explore(path.ToString());
  11:  
  12:    //顯示結果 (跨執行緒)
  13:    string text = $"{fileCount} files, {totalSize} bytes";
  14:    
  15:    //透過Invoke,強制以UI Thread執行
  16:    this.Invoke(
  17:        new UpdateLabelHandler(printResult),
  18:        new object[] { text });  
  19: }
  20: //宣告一個delegate
  21: delegate void UpdateLabelHandler(string text);
  22: //透過Invoke,printReulst會以UI Thread執行 
  23: //故可隨意存取UI Control
  24: private void printResult(string text)
  25: {
  26:    lblResult.Text = text;
  27: }


3.

利用.NET2.0 Backgroundworker

優點:簡單易上手
   1: private void runBtn_Click(object sender, EventArgs e)
   2: {
   3:     if(runBtn.Text == "Run")
   4:     {
   5:         runBtn.Text = "Cancel";
   6:         lblResult.Text = string.Empty;
   7:  
   8:         fileCount = 0;
   9:         totalSize = 0;
  10:         backgroundWorker1.RunWorkerAsync(txtPath.Text);
  11:     }
  12:     else
  13:     {
  14:         //設定取消旗標 
  15:         backgroundWorker1.CancelAsync();
  16:         //cancel = true; 
  17:         
  18:         //在完全停止前,停用按鈕 
  19:         runBtn.Enabled = false; 
  20:  
  21:     }
  22:  
  23: }
搜尋資料夾工作
   1: private void explortFolderJob(string path, BackgroundWorker worker)
   2: {
   3:     //使用遞迴搜索所有目錄 
   4:     foreach (string dir in Directory.GetDirectories(path))
   5:     {                
   6:         //使用者要求中止 
   7:         if (worker.CancellationPending) return;
   8:         explortFolderJob(dir, worker);
   9:     }
  10:  
  11:     foreach (string file in Directory.GetFiles(path))
  12:     {
  13:         //使用者要求中止 
  14:         if (worker.CancellationPending) return;
  15:  
  16:         Interlocked.Increment(ref fileCount);
  17:  
  18:         //每100個檔案回報一下進度
  19:         if(fileCount%100==0)
  20:         {
  21:             this.Invoke(
  22:                 new UpdateLabelHandler(updateProgress),
  23:                  $"{fileCount} files"
  24:             );
  25:         }
  26:  
  27:         //fileCount++;
  28:         //加總檔案大小 
  29:         FileInfo fi = new FileInfo(file);
  30:         totalSize += fi.Length;
  31:     }
  32: }
DoWork、ProgressChanged、RunWorkerCompleted
   1: private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
   2: {
   3:    explortFolderJob((string)e.Argument, sender as BackgroundWorker);
   4:    //執行完成,設執行定結果 
   5:    if (backgroundWorker1.CancellationPending)
   6:        e.Cancel = true;
   7:    else
   8:        e.Result = $"{fileCount} files, {totalSize} bytes";
   9: }
  10:  
  11: private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
  12: {
  13:    lblResult.Text = e.UserState.ToString();
  14: }
  15:  
  16: private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
  17: {
  18:    lblResult.Text = (e.Cancelled) ? "Canceled" : //取消
  19:        e.Result.ToString();                     // 結果
  20:    runBtn.Text = "Run";
  21:    runBtn.Enabled = true;
  22: }


非同步(Asynchronous)不在於提高效能(Performance),而是增加產能(Throughput)
非同步不等於多執行緒
非同步只對 I/O 相關作業有效,對吃 CPU 的作業沒轍
async 像病毒一樣會傳染




參考資料

------------------------------------------------------------------

1. C# 學習筆記:多執行緒 (1) - 從零開始

2. C# 學習筆記:多執行緒 (2) - 分道揚鑣

3. C# 學習筆記:多執行緒 (3) - 優先順序

4. 執行緒集區與 Execution Context (4)

5. C# 學習筆記:多執行緒 (5) — 工作の取消和逾時

6. C# 學習筆記:多執行緒 (6) — TPL

7. 不要寫「假的」非同步方法


------------------------------------------------------------------

1. ASP.NET async 基本心法

2. DKTD-WinFormThreading

3. TIPS-About UI Thread Limitation

4. KB-Keep Your Code Thread-Safe!

arrow
arrow
    全站熱搜

    me1237guy 發表在 痞客邦 留言(0) 人氣()