2011-01-08 163 views
1
  string desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);  
      public void unzip(String zFile) 
      { 
       Ionic.Zip.ZipFile zip = Ionic.Zip.ZipFile.Read(zFile); 
       zip.ExtractProgress += new EventHandler<ExtractProgressEventArgs>(zip_ExtractProgress); 
       zip.ExtractAll(desktop + "\\cache", ExtractExistingFileAction.OverwriteSilently); 
       zip.Dispose(); 
       zip = null; 
      } 

      void zip_ExtractProgress(object sender, ExtractProgressEventArgs e) 
      { 

       if (e.EventType == ZipProgressEventType.Extracting_EntryBytesWritten) 
       { 
        label2.Text = "debug: " + ((e.EntriesExtracted)); 
       } 
       else if (e.EventType == ZipProgressEventType.Extracting_BeforeExtractEntry) 
       { 
        label3.Text = e.CurrentEntry.FileName; 
       } 
      } 

      private void button1_Click(object sender, EventArgs e) 
      { 
       unzip(desktop + "\\cache.zip"); 
      } 

當我執行解壓縮button1_Click()我的應用程序凍結。我是C#的新手,我不確定如何解決這個問題,有人可以幫助我嗎?DotNetZip凍結我的應用程序?

回答

3

長時間運行阻塞操作不應該在主UI線程上運行,因爲您可以看到UI會凍結。

考慮使用BackgroundWorker在單獨的線程上完成工作。

有一個很好的摘要here

通過處理ProgressChanged事件並調用backgroundWorker.ReportProgress()而不是直接從裏面更新label2.Text來將進度報告回UI。

即從zip_ExtractProgress方法裏面,叫backgroundWorker.ReportProgress

+0

我試過使用後臺工作,但它一直說我的線程不安全。我該如何反擊?我讀過這個:http://msdn.microsoft.com/en-us/library/ms171728(v=VS.100).aspx但它不適合我。我一定是做錯了。 – Kyle 2011-01-08 15:28:01

+0

您可能直接從DoWork事件hander方法中更新UI。而是從連接到ProgressChanged的方法中更新您的UI,並使用backgroundWorker.ReportProgress()報告進度。您可以將您需要的任何對象從工作方法傳遞給ProgressChanged。 – tomfanning 2011-01-08 15:31:11

1

最簡單的方法:使用BackgroundWorker執行解壓方法。請務必使用Invoke僅在主GUI線程上修改GUI控件。

2
label3.Text = e.CurrentEntry.FileName; 
label3.Update(); 

Update()方法確保標籤被繪製,現在顯示您分配的Text屬性。沒有它,繪畫不會發生,直到解壓縮代碼停止運行並且程序再次空閒。否則稱爲「泵送消息循環」。調用Update()只是一個部分修復,你的窗口仍然是緊張的,並且不會響應鼠標點擊。如果花費時間超過幾秒鐘,Windows將顯示「Not responding」幻影窗口。

獲得一些C#編程經驗,然後用BackgroundWorker類處理線程。