我有一个算法。我想在某个时候暂停它,然后在用户按下按钮后继续。我怎么做?我浏览了文档,搜索了互联网,但还没有运气。
以下是相关的代码片段:
if A[i]>A[i+1]
then
begin
Zameni(i,i+1);
done:=true;
sleep(pauza);
br:=br+1;
end;
现在,我使用睡眠(pauza只是一个常数,意味着在塞尔维亚暂停)。理想情况下,我想用一个可以间隔睡眠的程序替换该行,或者根据配置设置等待按下按钮。
EDIT1:啊,是的,如果不是很明显 - 它是一个图形应用程序,而不是控制台,所以拍打“readln”将无法工作(遗憾)。
答案 0 :(得分:5)
这不是你如何做事件驱动的编程。您应该处理暂停点并在此时结束您的功能。在按钮按下事件处理程序中,然后执行剩余的处理 - 这只会在用户按下按钮时发生。您可以从OnTimer事件中调用相同的代码,以在给定的peruiod之后继续处理。
答案 1 :(得分:2)
使用线程和TThread类的内置暂停/恢复功能。 Jens Borrisholt写了一篇关于about.com here做一个很好的小例子文章。
如果在应用程序中引入多个ProcessMessage位置,则表单关闭时,其他事件的代码执行可能会出现问题。例如,如果在ProcessMessage“sleep”模式下关闭了表单,则没有好的方法来展开堆栈。
如果您使用的是DirectX / OpenGL,MessageDialog可能无法正常工作,因为您无法打开正常显示。调用MessageDialog可能会将视图从DirectX视图切换到普通桌面视图(丑陋但可行)或者它可以在普通桌面视图上显示消息而不更改DirectX的显示模式(使用户无法看到提示)。我和Dx合作已经有很长一段时间了,但我记得有关未能改变视图模式的问题很痛苦。
编辑:正如亚历山大指出的那样,你不应该从线程中的任何地方暂停线程(即,线程A可以挂起线程A而不是线程B)。如果您希望GUI线程暂停排序线程,请向排序线程发送消息并在排序线程内处理挂起。他的链接很好地讨论了为什么会这样。
答案 2 :(得分:1)
将i存储在静态变量中。在循环内部添加一个Pause标志的检查(由暂停按钮设置)。如果该标志为true,则退出该函数。再次单击暂停按钮时再次调用该功能。检查i的值,如果已经> 0只需进入你离开的循环。
当循环成功完成时,将i重置为0;
答案 3 :(得分:0)
您可以启动一个我们所做的对话框,一个简单的消息框就可以了,即
procedure TForm1.Pause1Click(Sender: TObject);
begin
// A dialog box will halt thread execution
Windows.MessageBox(0, 'Paused ...' + sLineBreak + 'Press Enter to Continue',
'', MB_OK);
end;
这可能只会暂停当前线程,如果你有多个线程,你可能想尝试更多参与。
答案 4 :(得分:0)
我不推荐它作为良好的应用程序设计,但如果没有其他建议适合您,您可能更喜欢这个。
在您的班级/表单中添加“已暂停:布尔”字段,并添加“继续”按钮。
开始操作时,将Paused设置为False,然后设置Continue.Enabled:= False;
当您的代码到达您要暂停的部分时:
Paused := True;
Continue.Enabled := True;
while Paused do
begin
sleep(100);
Application.ProcessMessages;
end;
在“继续”按钮事件处理程序中:
procedure Form1.ContinueClick(Sender: TObject);
begin
Paused := False;
Continue.Enabled := False;
end;
正如我之前所说,不是很漂亮,但它应该完成工作。
答案 5 :(得分:0)
虽然我同意线程方法,但我认为使用暂停/恢复是一个非常糟糕的主意。原因如下:http://blogs.msdn.com/oldnewthing/archive/2003/12/09/55988.aspx
创建一个线程并使用事件来暂停/恢复线程。简单。顺便说一下,你也可以使用像AsyncCalls这样的东西来简化线程创建(你不需要TThread类)。
创建一个单独的线程有另一个原因:你可以在后台进行繁重的计算,因此它们不会干扰UI。你的应用程序会有平稳的反应。
答案 6 :(得分:-1)
只需使用ReadLn;
ShowConsole("Enter to continue.");
ReadLn;