这听起来像是一个非常奇怪的问题。但是我从事的项目需要在其中包含圆形参考。实际上,它们甚至是不可避免的。因为用户可以在GUI中创建自己的循环引用。这是绝对有意的。。。请不要问为什么,这需要很多时间才能解释。
我发现讨论循环参考的所有问题,答案和资源,提供了有关如何避免参考的解决方案和方法。但是我没有读过关于如何制作一个解决方案的方法,但又不破坏底层的计算资源。
我看到的问题
在我看来,这样的特殊引用总有可能完全淹没底层系统,无论是要运行该程序的简单家用计算机还是研究型超级计算机。
这是由于我的理解,所提供的资源始终是有限的,但是循环引用本质上是无限的。
我看到的可能在这里出现问题的资源是:
如何减轻这些问题
缓解可以通过确保程序本身只能以很小的增量方式来增加其对计算资源的需求来进行。如果可以采取措施,那么基于收集的整个系统数据作为一个单元,我们可以决定是否甚至需要进一步改进以提高系统的感知质量。这将有助于我们限制对计算资源的需求。
我可以想象发生这种限制的方法之一是通过引入时间作为限制因素。该程序的设计方式应使其仅考虑在给定的时间后重新评估“自身”。如果这段时间和质量限制经过精心选择以匹配基础计算资源,那么我认为循环引用的资源问题可以得到缓解。
代码段
在下面找到一个非常简化的代码段。点1和点2本质上是完全独立的,它们甚至可以位于不同的线程上(实际上这是一个想法,该如何完成,但是我对多线程的理解不足以决定它是否是一种好的方法)。当它们连接到另一个对象时,操作首先开始。我不在乎“先这个然后那个”的行为是否以特定的方式发生。我唯一关心的是,这两个点之间的所有交互都是在将来的某个时刻(在附加之后)进行的。
namespace Circularity
{
class Program
{
static void Main(string[] args)
{
Point Point1 = new Point();
Point Point2 = new Point();
Point1.attach(Point2);
}
}
class Point
{
private ulong Value;
public Point()
{
Value = ulong.MaxValue / 2;
}
public void attach(Point otherPoint)
{
if (Value < ulong.MaxValue) Value++;
otherPoint.attach(this);
}
}
}
此代码立即导致堆栈溢出。但是我对堆栈的基本概念了解得不够,无法实施对策。我已经尝试在此处应用“时间”概念,但是堆栈溢出只需要更长的时间。
之所以会导致堆栈溢出,是因为您递归地调用attach
,因此您将继续添加堆栈帧,CLR无法处理那么多帧,并且正如您所看到的,它很快就会耗尽。这里的一种策略是使用Continuation Passing Style,从而避免构建方法调用堆栈。