5

C# でスレッドとメソッド呼び出しについて学び始めたばかりですが、解決策が見つからない問題に遭遇しました。

スレッドを開始してデリゲートを呼び出すことで、数値を更新して表示し続ける基本的な C# 形式のプログラムを作成しました。

Form1_load で新しいスレッドを開始:

private void Form1_Load(object sender, EventArgs e)
  {
        t = new System.Threading.Thread(DoThisAllTheTime);
        t.Start();
  }

Public void DoThisAllTheTime (番号を更新し続ける) :

public void DoThisAllTheTime()
  {
     while(true)
      {
        if (!this.IsDisposed)
         {
           number += 1;
           MethodInvoker yolo = delegate() { label1.Text = number.ToString(); };
           this.Invoke(yolo);
         }
      }
  }

フォームの X ボタンをクリックすると、次の例外が発生します。

'System.Windows.Forms.dll で 'System.ObjectDisposedException' 型の未処理の例外が発生しました

削除されたオブジェクトを更新できません'

フォームが破棄されたかどうかを実際に確認しましたが。

編集: 問題を修正したコードに catch (ObjectDisposedException ex) を追加しました。作業コード:

  public void DoThisAllTheTime()
  {
     while(true)
      {
         number += 1;

         try {  
              MethodInvoker yolo = delegate() { label1.Text = number.ToString(); };
              this.Invoke(yolo);
             }
         catch (ObjectDisposedException ex)
             {
              t.Abort();
             }
      }
 }
4

3 に答える 3

3

への呼び出しthis.IsDisposedは常に古くなっています。フォームを閉じるイベントをインターセプトし、スレッドを明示的に停止する必要があります。IsDisposedその後、そのテストをまったく行う必要はありません。

これを行うには多くの方法があります。個人的には、System.Threading.Tasks名前空間を使用しますが、 の使用を維持したい場合はSystem.Threading、メンバー変数 を定義_updateThreadし、ロード イベントで起動する必要があります。

_updateThread = new System.Threading.Thread(DoThisAllTheTime);
_updateThread.Start();

次に、クロージングイベントで:

private void Form1_Closing(object sender, CancelEventArgs e)
{
    _stopCounting = true;
    _updateThread.Join();
}

IsDisposed最後に、テストを新しい_stopCountingメンバー変数の値のチェックに置き換えます。

public void DoThisAllTheTime()
{
    MethodInvoker yolo = delegate() { label1.Text = number.ToString(); };
    while(!_stopCounting)
    {
        number += 1;
        this.Invoke(yolo);
    }
}
于 2013-10-27T15:51:45.397 に答える
2

このオーバーライドをフォーム クラスに入れるだけです。

protected override void OnClosing(CancelEventArgs e) {
    t.Abort();
    base.OnClosing(e);
}
于 2013-10-27T16:00:00.263 に答える
-3
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
Thread.CurrentThread.Abort();
}
于 2016-05-17T17:50:25.423 に答える