2010-01-14 76 views
1

我有一個運行在不同線程中的秒錶,它更新了標籤中的GUI線程以隨時間推移顯示。當我的程序關閉時,如果我在表單GUI中調用this.Invoke(mydelegate);來更新帶有秒錶時間的標籤,它會拋出ObjectDisposedExceptionObjectDisposedException - 在GUI線程中運行秒錶

我該如何擺脫ObjectDisposedException

我試圖停止FormClosing事件中的秒錶,但它不處理它。

下面的代碼:

System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); 
      stopwatch = sw; 

      sw.Start(); 
      //System.Threading.Thread.Sleep(100); 
      System.Threading.Thread t = new System.Threading.Thread(delegate() 
      { 
       while (true) 
       { 
       TimeSpan ts = sw.Elapsed; 

       string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", 
       ts.Hours, ts.Minutes, ts.Seconds, 
       ts.Milliseconds/10); 

       timeElapse = elapsedTime; 

        UpdateLabel(); 
       } 
      }); 
      stopwatchThread = t; 
      t.Start(); 

public void UpdateLabel() 
     { 
      db = new doupdate(DoUpdateLabel); 

      this.Invoke(db); 
     } 

public void DoUpdateLabel() 
     { 
      toolStripStatusLabel1.Text = timeElapse; 
     } 
+0

你可以發佈代碼嗎? – hackerhasid 2010-01-14 22:11:38

回答

2

它的樣子是當你關閉你的應用程序中的秒錶被佈置,但線程仍在運行,並試圖使用它。你可以在關閉應用程序之前停止你的線程(在FormClosing事件中)?

+2

我也強烈建議爲此使用BackgroundWorker。我很高興這解決了這個問題 – SwDevMan81 2010-01-14 22:28:15

2

相同的代碼,現在用一個BackgroundWorker,並確保表單不會關閉,直到後臺線程的有序關閉已停止運行第一:

using System; 
using System.Threading; 
using System.Windows.Forms; 
using System.Diagnostics; 

namespace WindowsFormsApplication1 { 
    public partial class Form1 : Form { 
     public Form1() { 
      InitializeComponent(); 
      backgroundWorker1.DoWork += backgroundWorker1_DoWork; 
      backgroundWorker1.ProgressChanged += backgroundWorker1_ProgressChanged; 
      backgroundWorker1.RunWorkerCompleted += backgroundWorker1_RunWorkerCompleted; 
      backgroundWorker1.WorkerReportsProgress = backgroundWorker1.WorkerSupportsCancellation = true; 
      backgroundWorker1.RunWorkerAsync(); 
     } 
     bool mCancel; 
     void backgroundWorker1_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e) { 
      if (e.Error != null) MessageBox.Show(e.Error.ToString()); 
      if (mCancel) this.Close(); 
     } 
     protected override void OnFormClosing(FormClosingEventArgs e) { 
      if (backgroundWorker1.IsBusy) mCancel = e.Cancel = true; 
      backgroundWorker1.CancelAsync(); 
     } 
     void backgroundWorker1_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e) { 
      label1.Text = e.UserState as string; 
     } 
     void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) { 
      Stopwatch sw = Stopwatch.StartNew(); 
      while (!backgroundWorker1.CancellationPending) { 
       TimeSpan ts = sw.Elapsed; 
       string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", 
        ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds/10); 
       backgroundWorker1.ReportProgress(0, elapsedTime); 
       Thread.Sleep(15); 
      } 
     } 
    } 
} 

注意睡眠()調用是必需的,它不可能每秒鐘以超過1000次的頻率封送對UI線程的調用。

+0

+1非常好!!!感謝那!!! :) – 2010-01-14 22:59:03