首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 跨執行緒操作 UI 控制項(三):Thread/ThreadStart 與 Control.Invoke 進階應用

     編輯:關於C語言

三、Thread/ThreadStart 下的跨執行緒操作控制項

在某些情境下(特別是工作執行緒眾多時),Thread/ThreadStart 仍具優勢。要在這類環境實現跨執行緒操作 UI 並不困難,代碼量也不會大幅增加,前提是你必須理解 Control.Invoke 方法。MSDN 說明:在擁有該控制項基礎視窗控制代碼的執行緒上執行委派。若留意第一張圖片的例外訊息,即可快速理解此方法的關鍵意義——它能讓工作執行緒中的委派在主執行緒中執行!因此實作思路是:在工作執行緒中使用委派來執行操作控制項的方法,再透過主視窗的 Invoke 方法調用。為實現 BackgroundWorker 的 ProgressChanged 與 RunWorkerCompleted 事件,定義了 ReportProcessInfo 與 DoneAfterCompleted 兩個委派。主要代碼如下:

// 實現 BackgroundWorker 的 ProgressChanged 事件
public delegate void ReportProcessInfo(string Info, int iPercent);
/// 實現 BackgroundWorker 的 RunWorkerCompleted 事件
public delegate void DoneAfterCompleted(string Info);

// 更新 ListView 與 ProgressBar 的方法
private void UpdateInfoToUser(string info, int percent)
{
    if (InvokeRequired)
        Invoke(new ReportProcessInfo(UpdateInfoToUser), info, percent);
    else
    {
        lvOutput.Items.Add(new ListViewItem(new string[] { System.DateTime.Now.ToLongTimeString(), info })).EnsureVisible();
        tssbProcess.Value = percent;
    }
}

// 清空來源/目標目錄資訊,顯示複製檔案數的方法
private void ShowUserFilesCountInfo(string info)
{
    if (InvokeRequired)
        Invoke(new DoneAfterCompleted(ShowUserFilesCountInfo), info);
    else
    {
        tbSource.Text = string.Empty;
        tbTargetDir.Text = string.Empty;
        MessageBox.Show(info);
    }
}

// 執行緒函數
private void CopyFiles(object SourceDir)
{
    DirectoryInfo di = (DirectoryInfo)SourceDir;
    int icur = 0;
    foreach (FileInfo fi in di.GetFiles())
    {
        icur++;
        tsslInfo.Text = string.Format("目前正在處理檔案:{0}", fi.Name);
        fi.CopyTo(Path.Combine(targetDir, fi.Name), true);
        CopyOneFileIsOK(fi.Name, GetPercent(icur, iFileCount));
    }
    CopyFilesIsCompleted(string.Format("本次操作共複製了 {0} 個檔案!", icur));
}

執行結果如下:

四、結語

代碼中的 InvokeRequired 用於判斷該段代碼是否在其他執行緒中透過委派調用;若為真,需在主執行緒中重新建立委派實例,並用 Invoke 方法調用,使代碼在主執行緒執行。

當需操作多個控制項時,建議使用 Form 的 InvokeRequired 判斷,並呼叫 Form 的 Invoke 方法調用新建的委派實例。若僅操作單一控制項(如 tbSource),則可直接使用該控制項的 InvokeRequired 與 Invoke。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved