1

MDI ベースのグラフ作成アプリケーションがあります。各子フォームは、グラフを含むフォームです。各グラフには、独自のデータ キューと専用のワーカー スレッドがあります。

ワーカー スレッドの DoWork メソッドには、グラフにデータをプロットする bool "IsChartActive" によって制御される while ループがあります。データをプロットするには、chartForm 自体で Invoke を呼び出し、グラフを更新するメソッドにデリゲートを渡します。

ユーザーがグラフ フォームを閉じると、実際に閉じるのではなく、グラフの更新を停止し、ユーザーが再度表示するまでグラフを非表示にしたいと考えています。

これを行うには、FormClosing イベントを処理し、Cancel = true に設定し、"IsChartActive = false" に設定して、ChartForm.Hide() を呼び出します。

しかし、この後、DoWork メソッドで「破棄されたオブジェクトにアクセスできません」という例外が発生します (これは、「IsChartActive = false」を設定したときにバックグラウンド スレッドが既に呼び出しステートメントにあるために発生すると想定しているため、変更が表示されます次の反復で)、チャートで invoke を呼び出すとき。

グラフが実際には破棄されておらず、非表示になっているだけなのに、なぜこの例外が発生するのですか?

public void StopChartUpdates()
        {
            IsActive = false;
            updateChartThread.CancelAsync();
        }


private void updateChartThread_DoWork(object sender, DoWorkEventArgs e)
        {
            while (IsActive && !updateChartThread.CancellationPending)
            {
                try
                {
                    ChartView.Invoke(new Action(InvokeOnUiThread));

                }
                catch (ObjectDisposedException ex)
                {
                              //getting this error when calling invoke on ChartView
                    Trace.WriteLine("Exception: " + ex.Message);
                }
                Thread.Sleep(UpdateFrequency);
            }
        }

private void InvokeOnUiThread()
        {
            try
            {
                       //update the chart
            }
            catch (Exception ex)
            {
                Trace.WriteLine("Exception: " + ex.Message);
            }
        }

private void ChartView_FormClosing(object sender, System.Windows.Forms.FormClosingEventArgs e)
        {
            StopChartUpdates();
            if (e.CloseReason == CloseReason.UserClosing)
            {
                ChartView.Hide();
                e.Cancel = true;
            }
        }
4

0 に答える 0