有两种形式。
不会自动创建Form2。
Form2:=TForm2.Create(Application);
Form2.Show;
如果要在任何表格中进行Sleep(10000);
,则会冻结另一个表格。如何防止这种行为?
我的问题:一个大文本文件(3 Mb)被连续分配(Lines.Assign
)到文本编辑器中,因此表单被冻结。
我可以使用其他未冻结的表单(非模态)来显示进度条(样式是pbstMarquee)吗?
答案 0 :(得分:6)
所有GUI代码都应该从主线程运行,看起来您遵循该规则。
如果你调用Sleep
,那么调用线程将不会执行代码,直到超时结束。如果从主线程调用Sleep
,则在超时结束之前不会抽取消息队列。因此,整个应用程序似乎都冻结了。
为什么从一个表单调用Sleep
会影响另一个表单?因为所有GUI组件都是从主线程的单个消息队列中提供的。一旦停止抽取该队列,所有GUI组件就会停止接收排队的消息,如WM_PAINT
,WM_KEYDOWN
等。
据我所知,您的问题是当您将3MB文本文件加载到编辑控件时,您的应用程序会显示为挂起。那个文件大小对我来说听起来不是很大,一个明显的解决方案是找到一个更好地执行加载的编辑控件。例如,我非常确定Notepad,Notepad ++等在加载此类文件时不会采取显示进度的步骤。我宁愿怀疑那些应用程序在加载文件时不会排队,但由于时间很短,你只是没有注意到。
您不希望发生的事情是您抽取队列以保持GUI响应,从而允许用户在第一个文件仍在加载时开始加载另一个文件。您需要在处理加载操作时禁用UI。模态进度对话框是一种方法。
如果无法切换到性能更佳的控件,可以显示模态进度对话框并使用这样的后台线程。后台线程会将文件加载到小块中,比如加入字符串列表。在文件的每个块准备好之后,它将调用Synchronize并获取主线程以将字符串列表的内容添加到编辑控件,然后清除字符串列表。然后线程将继续并加载下一个块。以小块添加到编辑控件将允许您保持消息队列的服务。
您可以在状态栏中显示进度,而不是模式对话框,这样可以减少干扰。但是请记住禁用任何会导致重入执行的UI。
答案 1 :(得分:0)
更好地在单独的线程中加载您的文件。或者您必须在普通的WinAPI中创建第二个表单,因为VCL不支持多线程。