我有一个控制台应用程序,它进行API调用并将数据返回到控制台。
我正在使用线程开始调用API并调用方法来获取最终调用自身的消息。此示例抛出StackOverFlowException。但是,如果我使用简单的while循环而不是它完美。
为什么它会在第一个代码示例中抛出StackOverFlowException,然后两个不同的方法实际上执行相同的工作?
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}");
}
}
}
答案 0 :(得分:4)
方法在完成所有操作(包括对自身的调用)之前不会完成。每次方法调用自身时,它都会将当前状态推送到堆栈上,因此当它返回时,它可以恢复其状态。
经常这样做,你会溢出堆栈。
要无限期地重复代码,您可以在while(true)
循环中代替。
PS。 IL has a "tail" method执行您希望代码执行的操作 - 完成当前方法并执行另一个 - 但它不包含在C#语言中。
答案 1 :(得分:0)
这个问题。
Exception in thread "main" java.net.BindException: Address already in use: Cannot bind
at java.net.DualStackPlainDatagramSocketImpl.socketBind(Native Method)
at java.net.DualStackPlainDatagramSocketImpl.bind0(DualStackPlainDatagramSocketImpl.java:84)
at java.net.AbstractPlainDatagramSocketImpl.bind(AbstractPlainDatagramSocketImpl.java:93)
at java.net.DatagramSocket.bind(DatagramSocket.java:392)
at java.net.DatagramSocket.<init>(DatagramSocket.java:242)
at java.net.DatagramSocket.<init>(DatagramSocket.java:299)
at java.net.DatagramSocket.<init>(DatagramSocket.java:271)
at ChatBox.Client.<init>(Client.java:44)
at ChatBox.Client.main(Client.java:140)
C:\Users\HP\AppData\Local\NetBeans\Cache\8.1\executor-snippets\run.xml:53: Java returned: 1
BUILD FAILED (total time: 0 seconds)
这将进入无限循环。并且GetMessages()方法将被调用无限时间,您需要在特定条件下断开此循环。
答案 2 :(得分:0)
两个片段之间的区别在于嵌套。如果您打电话给自己,在其他通话完成之前,您不会“退出”。
可视化:
-->GetMessagesInternal
--> GetMessagesInternal
--> GetMessagesInternal
--> GetMessagesInternal
--> etc
这将淹没堆栈,每个调用都保留在堆栈上
另一个:
-->GetMessagesInternal
-->GetMessagesInternal
-->GetMessagesInternal
-->GetMessagesInternal
-->etc