我有一个对象结构,它具有罕见的但可能的循环。 (循环是正常的。)使用递归方法遍历结构时,循环会导致堆栈溢出。与其在所涉及的方法中添加另一个参数,不如找出“ this”中的当前方法是否已经在堆栈中,将是一个不错的选择。有可能吗?
答案 0 :(得分:1)
我可能会选择一个ThreadLocal<T>
计数器,在打电话时增加计数器,在离开时减少计数器。这样,您可以分别计算在每个线程上输入的时间。这也比扫描堆栈快得多。也可以将其与布尔值一起使用,仅用于递归检查。
private ThreadLocal<int> _recursiveCounter = new ThreadLocal<int>(() => 0);
public void MyMethod(int count)
{
_recursiveCounter.Value++;
try
{
if(_recursiveCounter.Value > 2)
Trace.WriteLine($"Recursive exceeds 2 with {_recursiveCounter.Value}");
if(count== 0)
return;
MyMethod(count-1);
}
finally
{
_recursiveCounter.Value--;
}
}
当然,您可以将其包装在一个类中,然后将其与IDisposable
using(...)
组合在一起。
答案 1 :(得分:0)
我有一个非常相似的问题,以下是我如何解决的问题。基本上,我通过了HashSet<object>
并尝试将this
添加到该对象中。如果已添加,则this
尚未处理。
// Dummy class representing an element in the structure
public class A : Strcuture { }
// Dummy class representing an element in the structure
public class B : Strcuture { }
// Dummy class representing an element in the structure
public class C : Strcuture { }
// Base Dummy class for Base Structure elements
public abstract class Strcuture {
public List<Strcuture> Elements { get; } = new List<Strcuture>();
public void AddElement(Strcuture element) {
Elements.Add(element);
}
public void RecursiveMethod(HashSet<object> recursiveChecker) {
if(recursiveChecker == null){
recursiveChecker = new HashSet<object>();
}
var addedThis = recursiveChecker.Add(this);
if(addedThis == false) {
// this object has already been handled
// throw exception?? return early etc
throw new System.Exception("Already handled object");
}
foreach (var elem in Elements) {
elem.RecursiveMethod(recursiveChecker);
}
}
}
class Program
{
static void Main(string[] args)
{
var a = new A();
var b = new B();
var c = new C();
a.AddElement(b);
b.AddElement(c);
c.AddElement(a);
// now our object structure contains a loop
// A→B→C→A→B...
a.RecursiveMethod(new HashSet<object>());
}
}