0

バックグラウンド スレッドで毎秒 2000 の整数を生成するサンプル プログラムを作成しました。終了すると、ランダムに生成されたデータから GUI にグラフを描画するイベントが発生します (実際の測定をシミュレートするために、スレッド内でスリープ状態になっています)。 )。

private void SetChart(System.Windows.Forms.DataVisualization.Charting.Series series)
{
  if (InvokeRequired)
  {
    SetChartCallback d = new SetChartCallback(SetChart);
    this.Invoke(d, new object[] { series });
  }
  else
  {
    chart1.Series[0] = series;
    chart1.Series[0].Name = "Generated Data";
  }
}

MSDN サイトでこのアプローチを見つけました。正常に動作していますが、唯一の問題は、アプリケーションを閉じるときです。ときどきエラー メッセージが表示されます。

破棄されたオブジェクトにアクセスできません。
オブジェクト名: 'Form1'。

プログラムを閉じると、すべての要素が破棄されます。このエラーが発生しないようにするにはどうすればよいですか?

4

3 に答える 3

1

適切なアプローチは、醜く見えるかもしれませんが、おそらく例外をキャッチして飲み込むことです。バックグラウンド スレッドが終了するまでフォームをブロックするのはおそらく合理的ではありませんDispose(デッドロックが発生しやすい状況です)。また、フレームワークは、コントロールまたはフォームに対して try toInvokeまたはBeginInvokethis メソッドを指定するメソッドを提供しませんが、破棄された場合は何もしません。したがって、最善の策はおそらく、フォームが破棄された場合に発生する例外をキャッチすることによってそれを行うメソッドを作成TryInvokeするTryBeginInvokeことです。このようなメソッド内でチェックを使用することもできますIsDisposedが、フレームワークの癖が原因で、うまく解決できない競合状態がいくつかあることに注意してください。

于 2013-02-26T00:18:00.477 に答える
1

フォームを閉じましたが、スレッドはまだ実行されているため、完了すると、破棄されたオブジェクトでメソッドを呼び出そうとします。あなたのフォーム。

スレッドが完了するまで待つことができます。または、不要になった整数の作成をいじるのをやめて、今すぐループを終了するように信号を送ることができます。

ただ殺そうとしないでください。非常に悪い習慣です。あなたはそれに入りたくありません。

于 2013-02-26T00:07:18.863 に答える
0

解決策は、IsDisposed を確認することです。このようなもの:

private void SetChart(System.Windows.Forms.DataVisualization.Charting.Series series)
{
    if (IsDisposed)
       return;

    // ...
}
于 2013-02-25T23:51:39.333 に答える