1

У меня есть секундомер, работающий в другом потоке, который обновляет поток GUI на ярлыке, чтобы показывать время. Когда моя программа закрывается, она бросает ObjectDisposedException, когда я вызываю this.Invoke(mydelegate); в графическом интерфейсе формы, чтобы обновить метку со временем от секундомера.ObjectDisposedException - запуск секундомера в потоке графического интерфейса пользователя

Как избавиться от этого 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

ответ

2

Как выглядит это Секундомер расположен при закрытии приложения, но поток все еще работает и пытается использовать его. Можете ли вы остановить свой поток до закрытия приложения (в событии FormClosing)?

+2

Я также очень рекомендую использовать BackgroundWorker для этого. Я рад, что это решило проблему – SwDevMan81

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); 
      } 
     } 
    } 
} 

Обратите внимание, что вызов Sleep() требуется, это невозможно перевести вызовы в поток пользовательского интерфейса более чем 1000 раз в секунду.

+0

+1 Очень приятно !!! Спасибо за это!!! :) –