2011-11-20 48 views
1

我有一個基礎表單,在調用2個表單時使用。以前在調用表格時我沒有處理它們,但我發現重用它們,它們會留在記憶中而不被收集。所以我改爲使用using語句來清除內存,並且我的所有問題都已修復。具有基礎和線程的處置表單爲進度條返回空值

但是現在出現了一個新問題,我之前在Linux上使用單聲道測試我的應用程序時出現了一個新問題。我雖然可能是一個單一的特定問題,但自從添加使用語句,我的Windows機器上會發生同樣的事情。所以這可能就是Mono上的垃圾收集器不同,並正在處理我的表單。

這是我的問題我有一個線程,我開始在後臺提取文件我有進度條告訴我進度,在使用配置之前,如果我關閉表單並重新打開它,我的文件正確提取和進度酒吧工作正常。但是現在他們第一次工作的很好,但是如果我重新打開表單或另一個具有相同基數的表單,那麼提取不起作用,沒有文件被提取,因爲在報告進度時我有一個空異常。

private void ExtractFiles() 
    { 
     Zip.ExtractProgress += new EventHandler<ExtractProgressArgs>(Utils_ExtractProgress); 
     Thread t = new Thread(new ThreadStart(Zip.ExtractZip)); 
     t.IsBackground = true; 
     t.Start(); 
     FilesExtracted = true; 
    } 

    void Utils_ExtractProgress(object sender, ExtractProgressArgs e) 
    { 
     UpdateProgress(e.Pourcentage); 
    } 

    private delegate void UpdateProgressDelegate(int Pourc); 
    private void UpdateProgress(int Pourc) 
    { 
     lock (this) 
     { 
      if (Progress.ProgressBar.InvokeRequired) 
      { 
       UpdateProgressDelegate del = new UpdateProgressDelegate(UpdateProgress); 
       Progress.ProgressBar.BeginInvoke(del, Pourc); 
      } else 
      { 
       Progress.Value = Pourc; 

      } 
     } 
    } 

此代碼位於我的BaseForm中,Progress控件不爲null,但它的所有屬性均爲空例外。所以當檢查是否需要調用時,會引發Null異常。

這裏是我的Zip.Extract方法

public static event EventHandler<ExtractProgressArgs> ExtractProgress; 
    static ExtractProgressArgs Progress; 

    internal static void ExtractZip() 
    { 
     try 
     { 
      using (ZipFile zip = ZipFile.Read(Variables.Filename)) 
      { 
       Progress = new ExtractProgressArgs(); 
       Progress.TotalToTransfer = Convert.ToInt32(zip.Sum(e => e.UncompressedSize)); 
       zip.ExtractProgress += new EventHandler<ExtractProgressEventArgs>(zip_ExtractProgress); 
       Old = 0; New = 0; 
       foreach (ZipEntry item in zip) 
       { 

        item.Extract(Variables.TempFolder, ExtractExistingFileAction.OverwriteSilently); 
       } 
      } 
     } catch (Exception) 
     { 
     } 
    } 

    static long Old; 
    static long New; 
    static void zip_ExtractProgress(object sender, ExtractProgressEventArgs e) 
    { 
     if (e.EventType == ZipProgressEventType.Extracting_EntryBytesWritten) 
     { 
      New = e.BytesTransferred; 
      Progress.Transferred += New - Old; 
      Old = e.BytesTransferred; 

      if (ExtractProgress != null) 
      { 
       ExtractProgress(e.CurrentEntry, Progress); 
      } 

     } else if (e.EventType == ZipProgressEventType.Extracting_AfterExtractEntry) 
     { 
      Old = 0; 
     } 
    } 

可能是因爲我的Zip.Extract是靜態的?我幾乎沒有多線程知識,比如同步等。

回答

0

簡短的回答是肯定的,你的一些問題是由於這些操作的靜態性質。

您應該能夠通過從您的Zip類中移除靜態聲明並根據需要創建它的一個實例來解決問題。

+0

你誤會了我,我的BaseForm不是靜態的,但Zip.Extract方法是另一個類。將線程移至字段變量並在關閉語句中中止線程完全沒有幫助。 – Nigol

+0

我能夠編輯我的Zip.Extract並刪除靜態,並修復了它。無需在結語中終止線程。只是刪除不在我的基類,但Zip類的靜態定義。編輯你的答案,我會把它給你。 – Nigol

+0

對不起,我誤解了,但同樣的建議仍然適用:我會讓你的Zip類非靜態,然後以你想要使用它的形式創建它的一個實例。 –