【发布时间】:2017-02-13 21:14:16
【问题描述】:
我正在尝试创建对方法的递归调用但收到错误:
无法计算表达式,因为当前线程在堆栈中 溢出状态
只是一点背景知识,我正在迁移一个 PowerBuilder 应用程序。到 C#.NET windows 应用程序,PB 应用程序。有一个以编程方式完成的计时器,它将在特定时间执行 main 方法。 PB 代码在两台机器上运行,一个计时器设置在 '0' 标记处,而在 #2 机器上,它设置在 30 秒标记处。
PB 代码如下:
ue_wait event:
gi_offset = //Global variable set at the application open event, equivalent to program.cs - main event. Will be 0 or 30 depending on the machine.
li_difference = Integer( String( Now(), 'ss')) //Gets the seconds from the current date time.
DO UNTIL li_difference = gi_offset
ls_status = 'current second: ' + String( Now(), 'ss') + ' starting on:' + String( gi_offset)// Builds a string to display in a static text control in PB, label in C#.
IF st_status.Text <> ls_status THEN st_status.Text = ls_status
Yield()
li_difference = Integer( String( Now(), 'ss'))
LOOP
//execute main processing method.
ue_action().
//End of event
ue_action event
Do main processing.
Call ue_wait()
下面是我的 C# 代码:
private void Form1_Shown(Object sender, EventArgs e)
{
ue_wait();
}
private void wf_actions_Load(object sender, EventArgs e)
{
//Should fire after all of the form has loaded.
Shown += Form1_Shown;
}
private void ue_wait()
{
long todays_date_in_seconds = DateTime.Now.Second;
long ll_global_offset = 0;
string ls_status = "";
todays_date_in_seconds = DateTime.Now.Second;
while (!(todays_date_in_seconds == ll_global_offset))
{
ls_status = "Current second: " + DateTime.Now.Second.ToString() + " starting on: " + ll_global_offset.ToString();
lbl_status.Text = ls_status;
todays_date_in_seconds = DateTime.Now.Second;
}
ue_action();
}
private void ue_action()
{
//After the main processing is done, it goes back to ue_wait().
ue_wait();
}
所以我尝试了在 Inet 上找到的两种可能性:
this.Shown += new System.EventHandler(this.Form1_Shown);
this.Activated += AfterLoading;
但是,当调用 ue_action 时,我在 ue_wait 事件中都收到以下错误...
{无法计算表达式,因为当前线程在堆栈中 溢出状态。}
第一行失败:long todays_date_in_seconds = DateTime.Now.Second;
我找到了 .NET 计时器,但它不允许您在特定时间点设置开始,即:秒、Timer.Start() = 0 标记或 Timer.Start() = 30 秒标记(30000 毫秒)。间隔是可以工作的一部分,因为我可以将其设置为每 60 秒执行一次。
做了一些谷歌搜索后,因为有“递归”编程,这导致了“堆栈溢出”,我怎样才能避免 .NET 环境中的“堆栈溢出”,或者是否有另一种方法来做我需要的在 C#.NET 环境中做什么?
【问题讨论】:
-
我没有看到
ue_action和ue_wait方法有任何救助或提前回报。这两者怎么不会无限互相调用(从而导致堆栈溢出)? -
ue_action调用ue_wait调用ue_action调用ue_wait调用ue_action调用ue_wait调用ue_action调用ue_wait调用@9876543调用ue_wait调用ue_action调用ue_wait调用(你明白了)。无限循环是任何语言的无限循环,与 .NET 无关。 -
我知道这是一个无限循环,这就是它在 PB 应用程序中的完成方式。该应用程序 24/7 运行并在自身内部不断循环以构建计时器并处理它需要在 ue_action 事件中处理的内容,然后继续返回 ue_wait 等...... DO UNTIL 循环中有 Yield() 函数Yield 控制其他图形对象,包括不是 PowerBuilder 对象的对象。Yield 检查消息队列,如果队列中有消息,它会将它们从队列中拉出。"。不确定此功能是否有助于堆栈溢出,可能在 .NET 中类似。
-
.NET 有一个
Application.DoEvents方法,它的作用类似,但这是一种完全错误的方法。我怀疑您是否想将单个 CPU 内核旋转到 100% 只是为了每秒触发一个事件。在任何语言中使用循环进行计时都是一个坏主意,如果您可以使用简单的计时器,您甚至不会在 8051 微控制器中使用它。 -
我同意你的看法,PB 应用程序是在 2004 年编写的,但开发工具没有像 .NET 这样的计时器控件。我自己是一名 PB 开发人员,我的大脑围绕着 .NET。感谢您的意见。