报错原因: 因为使用了递归,当调用的深度过深,则会引发内存溢出从而触发.net的保护机制,导致程序中断。
经过两天的奋战,终于完美解决了这个问题,接下来Share一下我的解决过程,没有耐心看的可以直接滑到底部,查看最终的解决方案。
详细报错信息截图:
----------解决过程分享----------
在网上冲浪找了很久,总结了一下网友们提供的两个解决方案,为:
1.使用Thread.Sleep(1000)
我使用后的结论: 除了会降低递归的速度以外,并没有其他帮助,未能解决问题。递归到一定的量,占用足够的内存时照样会提示报错System.StackOverflowException。
2.改变递归的写法
原先的递归写法:
public void MethodA()
{
if ()
{
}
else
{
this.MethodA();
}
}
改为:
public void MethodA()
{
if ()
{
}
else
{
this.MethodB();
}
}
public void MethodB()
{
if ()
{
}
else
{
MethodA();
}
}
他对这两种的写法解释为:比较两种写法,第一种写法不断的递归,函数嵌套层数过多最后导致栈内存溢出,而第二种写法将循环的部分放到了另外一个函数,进入MethodB的时候MethodA已经结束了,其占用的栈内存可以得到释放,所以没有过多的函数嵌套。
我使用后的结论: 除了实现递归的写法变得复杂以外,并没有其他帮助,未能解决问题。递归到一定的量,占用足够的内存时照样会提示报错System.StackOverflowException。
----------最终的解决方案----------
在你调用递归的方法那里,加入两行代码,最终代码:
private int iQty = 0;
public void MethodA()
{
if ()
{
}
else
{
this.MethodB();
}
}
public void MethodB()
{
if ()
{
}
else
{
iQty++;
if(iQty % 10 == 0)
{
//这里加多一个判断,每当循环十次后,就使用新线程的方式来调用方法,主要是为了释放之前的内存,避免内存溢出。
var t = new Thread(delegate () { MethodA(); }, 1073741824);
t.Start();
}
else
{
MethodA();
}
}
}
MethodA() --> 递归调用的方法
1073741824 --> 最大堆栈大小
运行后,测试,完美解决!!!
加入这两行代码的作用: 实例化开启新的线程并委托递归调用的方法,这样就能和之前的进程分离,释放之前线程占用的内存。指定新的线程最大堆栈大小,防止递归调用的方法会内存溢出。