防止在子窗体终止时销毁另一个窗体引用的对象

本文关键字:窗体 另一个 引用 对象 终止 | 更新日期: 2023-09-27 18:28:29

我有以下问题:图表系列的数组从一个窗体传递到另一个窗体,以便在子窗体中可视化。我这样做是为了扩大主窗口中图表的查看区域。这一切都很好,直到我关闭我的系列已经传递到的第二个表单,此时我的应用程序压碎了一个空对象引用。现在我怀疑我的系列已经在表单终止时被垃圾收集了。有什么想法吗?如何在不破坏数据的情况下修复并安全关闭该表单?

这是创建表单的代码。

Series[] tpSeries = { chart2.Series["S1"], chart2.Series["S2"] };
Dictionary<string, NumericUpDown> netParams = new Dictionary<string, NumericUpDown>()
{ 
 {"N", numVertecies},
 {"S", numS},
 {"R", numR},
 {"Gamma", numGama},
 {"Beta", numBeta},
 {"G", numG},
 {"C0", numCzero},
};
TimePlotAnalysis tpForm = new TimePlotAnalysis(tpSeries, netParams); // N, s, r, gamma, beta, g, c_0 
tpForm.Show();

防止在子窗体终止时销毁另一个窗体引用的对象

基本上,您的数据应该在一个单独的类中,然后您只需在表单之间共享一个类实例。

根据您的特定用例,有很多不同的方法可以做到这一点。以下是几个例子:

  • 如何在表单之间共享数据?

  • 使用C#在两个表单之间传递值

  • http://colinmackay.scot/2005/04/22/passing-values-between-forms-in-net/

根据您的具体需求,您可能希望将此对象实现为"singleton":

  • http://csharpindepth.com/Articles/General/Singleton.aspx

现在我怀疑我的系列已经在表单终止时被垃圾收集了。

这个问题与GC没有任何共同之处。您将Series对象的数组从一个表单中的图表控件传递到另一个表单,其中(尽管您没有显示)我怀疑您将它们添加到了另一个图表控件中。

让我们来看看Series类文档。

继承层次结构
System.Object
System.Windows.Forms.DataVisualization.Charting.ChartElement
System.Windows.Forms.DataVisualization.Charting.ChartNamedElement
System.Windows.Forms.DataVisualization.Charting.DataPointCustomProperties
System.Windows.Forms.DataVisualization.Charting.Series

按照层次结构,以下是基类定义

public abstract class ChartElement : IDisposable

注意IDisposable?现在我想你明白发生了什么。关闭第二个窗体时,会对该窗体和所有控件调用Dispose方法。正确的dispose实现将反过来对它们持有的任何一次性对象调用dispose(我们可以假设MS控件do正确地实现了一次性模式)。

很快,我认为传递到第二个表单的Series对象被处理掉了。

为了解决这个问题,正如Reza Aghaei在他的评论中正确指出的那样,不应该将Series对象传递给第二个表单,而应该将允许在那里重新创建它们的数据传递给第三个表单。或者至少要确保您确实从传递的对象中创建了一个新的Series对象