通过再次调用相同的方法,循环期间出现C#StackOverFlow异常
我有一个控制台应用程序,它进行API调用并将数据返回控制台 我正在使用线程开始调用API并调用方法来获取最终调用自身的消息。此示例抛出StackOverFlowException。但如果我使用简单的while循环,它的工作就完美了 为什么它在第一个代码示例中抛出StackOverFlowException,然后两个不同的方法实际执行相同的工作通过再次调用相同的方法,循环期间出现C#StackOverFlow异常,c#,multithreading,exception,C#,Multithreading,Exception,我有一个控制台应用程序,它进行API调用并将数据返回控制台 我正在使用线程开始调用API并调用方法来获取最终调用自身的消息。此示例抛出StackOverFlowException。但如果我使用简单的while循环,它的工作就完美了 为什么它在第一个代码示例中抛出StackOverFlowException,然后两个不同的方法实际执行相同的工作 var thread = new Thread(GetMessagesInternal); thread.Start(); private static
var thread = new Thread(GetMessagesInternal);
thread.Start();
private static void GetMessagesInternal() { //THROWS STACKOVERFLOWEXCEPTION
var messages = MyProgram.GetMessages();
foreach (var message in messages) {
Console.WriteLine($"{message.MessageText}");
}
GetMessagesInternal();
}
private static void GetMessagesInternal() { //WORKS FINE
while(true) {
var messages = MyProgram.GetMessages();
foreach (var message in messages) {
Console.WriteLine($"{message.MessageText}");
}
}
}
方法在完成所有操作(包括对自身的调用)之前不会完成。每次方法调用自身时,它都会将当前状态推送到堆栈上,因此当它返回时,可以恢复其状态 这样做太频繁,会使堆栈溢出 要无限期地重复代码,您可以改为在
while(true)
循环中重复代码
注:这就是您希望代码执行的操作—完成当前方法并执行另一个方法—但它不包含在C语言中。方法只有完成所有操作(包括对自身的调用)后才能完成。每次方法调用自身时,它都会将当前状态推送到堆栈上,因此当它返回时,可以恢复其状态 这样做太频繁,会使堆栈溢出 要无限期地重复代码,您可以改为在
while(true)
循环中重复代码
注:这就是您希望代码执行的操作——完成当前方法并执行另一个方法——但C语言中不包含它。这是一个问题
private static void GetMessagesInternal() //WORKS FINE
{
while(true)
{
var messages = MyProgram.GetMessages();
foreach (var message in messages)
{
Console.WriteLine($"{message.MessageText}");
}
}
这将在无限循环中进行。并且GetMessages()方法将在需要在特定条件下中断此循环的无限时间内被调用。此方法的问题
private static void GetMessagesInternal() //WORKS FINE
{
while(true)
{
var messages = MyProgram.GetMessages();
foreach (var message in messages)
{
Console.WriteLine($"{message.MessageText}");
}
}
这将进入无限循环。如果在特定条件下需要中断此循环,则GetMessages()方法将在无限时间内被调用。这两个代码段之间的区别在于嵌套。如果你给自己打电话,在另一个电话结束之前,你不会“退出” 可视化:
-->GetMessagesInternal
--> GetMessagesInternal
--> GetMessagesInternal
--> GetMessagesInternal
--> etc
这将淹没堆栈,每个调用都保留在堆栈上
另一个:
-->GetMessagesInternal
-->GetMessagesInternal
-->GetMessagesInternal
-->GetMessagesInternal
-->etc
两个代码段之间的区别在于嵌套。如果你给自己打电话,在另一个电话结束之前,你不会“退出” 可视化:
-->GetMessagesInternal
--> GetMessagesInternal
--> GetMessagesInternal
--> GetMessagesInternal
--> etc
这将淹没堆栈,每个调用都保留在堆栈上
另一个:
-->GetMessagesInternal
-->GetMessagesInternal
-->GetMessagesInternal
-->GetMessagesInternal
-->etc
谷歌“无限递归”很抱歉,但在你提问之前,也许你应该在调试器中逐步检查你的代码。你要求人们花时间来帮助你。你至少可以花点时间来找出自己出了什么问题。谷歌“无限递归”很抱歉,但在你提问之前,也许你应该在调试器中逐步检查你的代码。你要求人们花时间来帮助你。你至少能做的是花点时间试着弄清楚自己出了什么问题。嗯,他说这很管用。他对另一个代码片段的问题。我希望while(true)将作为MyProgram.GetMessages()得到无限数执行。这个方法将得到调用无限时间,顺便说一句,它可以工作,然后就不重要了。嗯,他说它工作得很好。他对另一个代码片段的问题。我希望while(true)将作为MyProgram获得无限次数的执行。GetMessages()此方法将获得调用无限时间,顺便说一句,它可以工作,然后就不要紧了。实际上,ryujit在某些情况下会进行TCO(SO发现在实现中甚至有一个有趣的bug)。因此,如果使用正确的选项运行,代码实际上可以表现出相同的行为(我假设tco只在发行版中完成)。实际上,ryujit在某些情况下执行tco(So人员发现的实现中甚至有一个有趣的bug)。因此,如果使用正确的选项运行,代码的行为实际上可能完全相同(我假设tco只在发行版中完成)。