2009-11-15 53 views
1

我做「大」文件中的一些操作(約4MB)的WinForms:避免凍結申請

我這樣做:1。 從目錄中獲取所有文件,並將它們放置在一個IList MyInfoClass有屬性:名稱,擴展名,fullPath,creationDate,contentPart 2.我做一個Linq查詢來獲得一些擴展類型。 3.我在Linq查詢結果上循環,併爲每個打開文件,執行一些操作(獲取值)並將結果放入MyFileIno.ContentPart中。

FYI:30個文件,這是一個14sec操作

這就是工作。

問題是,當我從UI運行我的庫時,當我單擊按鈕時,窗口在操作期間凍結。我想:

  1. 解決被凍結的形式
  2. 看到進度操作

你能不能給我解決這類問題的最佳做法是什麼?

感謝,

代碼

public class FileManager 
{ 
    public string CurrentFileName { get; set; } 
    public void Validation(string path) 
    { 
     IList<InfoFile> listFile = GetListFile(path); 
     foreach (InfoFile item in listFile) 
     { 
      CurrentFileName = item.Name; 
      ..... 
     } 
    } 
} 


private void button1_Click(object sender, EventArgs e) 
{ 
    var worker = new BackgroundWorker(); 
    worker.DoWork += (s, args) => 
    { 
     int percentProgress = 6; 
     FileManager fileManager = new FileManager(); 
     fileManager.Validation(@"C:....."); 
     ((BackgroundWorker)s).ReportProgress(percentProgress, fileManager.CurrentFileName); 
    }; 

    worker.ProgressChanged += (s, args) => 
    { 
     var currentFilename = (string)args.UserState; 
     label1.Text = currentFilename; 
     progressBar1.Value = args.ProgressPercentage; 
    }; 

    worker.RunWorkerCompleted += (s, args) => 
    { 
     progressBar1.Value = 0; 
    }; 
    worker.RunWorkerAsync(); 
} 

回答

15

申請凍結,因爲你正在執行的文件,在主線程解析。您可以使用BackgroundWorker在新線程上執行操作。以下是一些可幫助您開始使用的僞代碼:

private void button1_Click(object sender, EventArgs e) 
{ 
    var worker = new BackgroundWorker(); 
    worker.DoWork += (s, args) => 
    { 
     // Here you perform the operation and report progress: 
     int percentProgress = ... 
     string currentFilename = ... 
     ((BackgroundWorker)s).ReportProgress(percentProgress, currentFilename); 
     // Remark: Don't modify the GUI here because this runs on a different thread 
    }; 
    worker.ProgressChanged += (s, args) => 
    { 
     var currentFilename = (string)args.UserState; 
     // TODO: show the current filename somewhere on the UI and update progress 
     progressBar1.Value = args.ProgressPercentage; 
    }; 
    worker.RunWorkerCompleted += (s, args) => 
    { 
     // Remark: This runs when the DoWork method completes or throws an exception 
     // If args.Error != null report to user that something went wrong 
     progressBar1.Value = 0; 
    }; 
    worker.RunWorkerAsync(); 
} 
+0

謝謝。關於圖形用戶界面的好評,我得到了例外... :)而不是percentProgress,我想在治療中使用文件名,爲什麼沒有百分比? –

+0

您可以使用'BackgroundWorker.ReportProgress(int,object)',其中第二個參數是您可以在'ProgressChanged'回調中通過'args.UserState'使用的自定義用戶狀態對象。 –

+0

我已經更新了我的回答,以考慮到這一點。 –