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

您已经关闭了表单,但线程仍在运行,因此当它完成时,它会尝试调用已处置对象上的方法。你的表格。

您可以等待线程完成。或者您可以以某种方式向它发出信号以停止创建您不再需要的整数并立即退出它的循环。

不要试图杀死它。非常坏的习惯,你不想进入那个。

于 2013-02-26T00:07:18.863 回答
1

正确的方法,虽然看起来很丑陋,但可能是捕获异常并吞下它。Dispose在后台线程退出之前阻止表单可能是不合理的(这种情况很容易导致死锁);框架也没有提供任何方法来尝试InvokeBeginInvoke在控件或表单上使用此方法,但如果它已被处置,则根本不做任何事情。因此,您最好的选择可能是编写TryInvokeTryBeginInvoke方法,通过捕获表单已被处理时产生的任何异常来实现这一点。您可能会在这种方法中使用IsDisposed检查,但您应该意识到,由于某些框架怪癖,有些竞争条件无法很好地解决。

于 2013-02-26T00:18:00.477 回答
0

一个解决方案可能是检查 IsDisposed。像这样的东西:

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

    // ...
}
于 2013-02-25T23:51:39.333 回答