有两种形式。德尔福:冻结形式
Form2不是自动创建的。
Form2:=TForm2.Create(Application);
Form2.Show;
如果要做任何形式的Sleep(10000);
然后另一个将被冻结。如何防止这种行为?
我的问题:一个大的文本文件(3 MB)连续分配(Lines.Assign
)到文本编辑器,这样一种形式被冻结。
我可以用另一种形式解冻(非模态)来显示进度条(一种风格是pbstMarquee)?
有两种形式。德尔福:冻结形式
Form2不是自动创建的。
Form2:=TForm2.Create(Application);
Form2.Show;
如果要做任何形式的Sleep(10000);
然后另一个将被冻结。如何防止这种行为?
我的问题:一个大的文本文件(3 MB)连续分配(Lines.Assign
)到文本编辑器,这样一种形式被冻结。
我可以用另一种形式解冻(非模态)来显示进度条(一种风格是pbstMarquee)?
所有GUI代码都应该从主线程运行,并且看起来好像遵循了该规则。
如果调用Sleep
然后调用线程将不执行代码,直到超时时间。如果您从主线程调用Sleep
,则消息队列在超时过后才会被泵送。因此,整个应用程序似乎冻结。
为什么从一种形式调用Sleep
会影响另一种形式?因为所有GUI组件都来自主线程的单个消息队列。一旦你停止泵送队列,所有的GUI组件停止接受排队的消息像WM_PAINT
,WM_KEYDOWN
等
据我了解你的问题是,当你加载3MB文本文件导入编辑控件应用程序将出现挂起。文件的大小对我来说听起来不是很大,一个明显的解决方案是找到一个更好地执行加载的编辑控件。例如,我非常确定记事本,Notepad ++等在加载这些文件时不需要像显示进度那样的步骤。我相当怀疑这些应用程序在加载文件时不会抽出队列,但由于时间短,您不会注意到。
什么你不希望发生的事情是你抽你的队列,让您的GUI响应,进而允许用户启动加载另一个文件,而第一个仍在加载。您需要在处理加载操作时禁用您的UI。模态进度对话框是实现这一目标的一种方式。
如果您无法切换到性能更好的控件,则可以显示模式进度对话框并使用像这样的后台线程。后台线程可能会以小块加载文件,比如放到一个字符串列表中。在文件的每个块都准备好之后,它会调用Synchronize并让主线程将字符串列表的内容添加到编辑控件中,然后清除字符串列表。该线程将继续并加载下一个块。向小块中添加编辑控件可以让您保持消息队列的服务。
你可以在状态栏中显示进度,而不是模式对话框,这样做不那么具有侵入性。但是请记住禁用任何会导致可重入执行的UI。
更好地加载您的文件在一个单独的线程。或者您将不得不在纯WinAPI中创建第二个表单,因为VCL不支持多线程。
睡眠()函数的定义本身是“冻结这个线程”,如果你冻结了主线程,你只能从主线程冻结你所有的形式,因为他们所有的工作。听起来你需要了解win32应用程序设计中消息泵的重要性。 http://en.wikipedia.org/wiki/Event_loop –
有没有*有*真正的理由叫睡眠? –
在前台线程?没有。即使在后台线程中,WaitForSingleObject也会更好。我认为OP使用Sleep()模拟3mb文本文件加载多长时间。 –