如何在函数的 N 次递归调用中中断程序?
Posted
技术标签:
【中文标题】如何在函数的 N 次递归调用中中断程序?【英文标题】:How do I break a program at N recursive call of a function? 【发布时间】:2019-06-14 11:00:09 【问题描述】:我的程序中有一个递归调用:
Left?.Generate(ref result, ref resultGiven);
当这个Generate()
函数被调用6 次时,我想调试我的程序并停止执行。我该怎么做?
【问题讨论】:
添加一个计数器并在达到 6 时退出? 使用 Debugger.Launch() if counter = 6; 【参考方案1】:最简单的方法是使用全局变量。
// somewhere before Generate first call
var counter = 0;
void Generate(ref result, ref resultGiven)
if (counter == 6)
return;
counter++;
// the rest of function's body
【讨论】:
您正在限制函数的 any 调用:Generate
的执行次数不能超过 6
次。但是,OP 似乎想要限制递归的深度(Generate
不能调用自身超过6
次)。
@DmitryBychenko,我不确定,但主题名称中包含“破坏程序”字样,所以我认为这些情况之间没有区别。
@DmitryBychenko,哎呀,我只是想“中断程序”可能意味着“停止执行”而是“创建断点”。在这种情况下,您的方法当然是可取的。【参考方案2】:
如果我没有理解错,你想限制递归的深度(即不要让Generate
调用自己超过6
次) .如果是你的情况,你可以试试StackTrace这个类:
using System.Diagnostics;
...
void Generate(ref result, ref resultGiven)
// --- Comment this out after debugging
string currentFrame = new StackTrace(new StackFrame(false)).ToString().Trim();
StackTrace trace = new StackTrace();
int depth = trace
.ToString()
.Split(new char[] '\r', '\n' , StringSplitOptions.RemoveEmptyEntries)
.Where(frame => frame.Trim() == currentFrame)
//.TakeWhile(frame => frame.Trim() == currentFrame) // if direct calls only
.Count();
// Prevent Generate to call itself more than 6 time
if (depth > 6)
// Maximum depth reached, return or launch debugger - Debugger.Launch()
return;
// --- Comment this out after debugging
...
【讨论】:
不...只是不。不要对这么简单的事情使用反射。 这同时也是对反射最恶魔和最天才的使用!喜欢它! @riffnl:这不是那么简单。如果Generate
从例程的不同部分使用不同的参数调用会怎样?让我们加重一下:同时从不同的线程?
所以这就是你添加参数的原因(例如默认为 0:不需要调整任何东西和线程安全)。为此使用反射就是用大锤敲碎坚果。【参考方案3】:
使用计数或步长参数就足够了;
Left?.Generate(ref result, ref resultGiven); // is same
函数看起来像这样:
void Generate(object ref result, object ref resultGiven, int step = 0)
// do stuf
// break for debug
if (step >= 6)
return;
// or only break when debugger is attached
if (System.Diagnostics.Debugger.IsAttached && step >= 6)
return;
// recursive
Generate(ref result, ref resultGiven, step++);
【讨论】:
这还不够(一般情况下):假设Generate
调用方法Foo
调用Generate
。在您的方法中,我们也必须更改Foo
。
没错,但这不再是(严格来说)递归了。以上是关于如何在函数的 N 次递归调用中中断程序?的主要内容,如果未能解决你的问题,请参考以下文章