delphi运行时主界面卡死

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了delphi运行时主界面卡死相关的知识,希望对你有一定的参考价值。

如题,delphi在调用外部dll时,由于dll中的运算量比较大,主界面会卡死,请问哪位大神知道解决方法?感谢您的分享!

第一种情况:dll 是别人写的,你调用。

如果是这样子,在不改动dll时是无法解决主界面卡死的问题;但是能改动dll的话,在循环语句里,延时语句里写上,这也是最简单的做法。

Application.ProcessMessages;

注:你在不改动dll的情况下,使用线程去调用的,因为并不知道dl里面的函数、变量,尤其是全局变量等支不支持线程,产生异步等问题;并且如果运算量大的话,线程并不能节省时间,而且会更加耗时间。


第二种情况:dll是你自己写的,这样子就会好解决,也在dll的循环语句里,延时语句里,运行时间久的地方加上上述语句。

追问

dll是通过其他编程软件编译的,无法写进Application.ProcessMessages

追答

暂时无解,如果确实需要改动,可以联系这个写DLL的人,要他改下;如果不能改,就将就着用吧。或者自己丰衣足食重写DLL.
但是你可以试下 他们2位的办法,试试运行会不会出异常。

追问

好的,谢谢!

参考技术A 有试过把调用和运算的代码放到线程中去执行吗?貌似一般运算量大,需要的运算时间长的代码都是放到线程中运行的追问

dll中内容不可见,也能写到线程中去吗?

追答

能写到主程序里面去就能写到线程中去,你在主程序中怎么写的再线程中就是怎么写的,你只要确定好参数、数据这些的入口就好了

追问

线程方面本人小白一个,能举个例子说明一下吗?感激不尽!

追答

我只能比较简单的回答你这个问题
线程的代码是写在线程单元文件中的,线程单元你可以通过file>new>other>thread object来创建线程单元代码,实际上线程也就是个类,你创建了单元以后就明白了,网上有很多关于线程的教程,甚至还有实例,我这里就不列出来了,没那么大的篇幅,你可以自己去搜索,一般情况下也只有出现了计算量很大,需要的时间非常长的时候才会使用线程,最简单的例子:
将一个integer类型从0循环到50000并显示在窗体里面,如果你直接在主线程中运行这个for循环的话,那么在循环的时候窗体就会像你现在这样被卡死,那么如果你用了线程的话,那么数字在循环的时候你的窗体还是一样可以拖动,变大变小,不会受到影响,主要的代码是这样:
unit1中
uses unit2//这个是线程代码的单元
var
Form1: TForm1;
threadtest:test; //test是线程名称
procedure TForm1.Button1Click(Sender: TObject); //点击按钮以后进入线程
begin
threadtest:=test.Create(false);
end;

unit2中
uses unit1

procedure test.Execute; //这个过程是delphi自动定义的线程的运行过程,这里面我进行了循环
var
i:integer;
begin
Place thread code here
for i:=0 to 5000 do
begin
unit1.Form1.Label1.Caption:=inttostr(i);
end;
end;
如果你将这个for循环放在主线程也就是unit1中运行的话,循环不结束你就不能动这个窗口,把这个循环放在线程中就没关系了,另外你不想弄那么麻烦的话还有一个不是很好用的方法,就是在你计算的时候加入这样一行代码:application.ProcessMessages;
这个代码可以让你的程序在运行过程中前一个事务结束后让窗体相应你的操作,但是相对于线程来说,没那么好用,而且比较死,如果你在这个时候操作了窗体,那么你的代码后台就会停下来,一直等你的操作结束,才会继续运行,运行的时候窗体又不会响应你了

本回答被提问者采纳
参考技术B type
TMyThread = class(TThread)
protected
procedure Execute;
override;
end; 开启线程

procedure TMyThread.Execute;
var
i: Integer;
begin
这里写操作过程
end;
end;

TMyThread.Create(False); //调用方法追问

谢谢您的帮助!

C# 耗时的程序 界面卡死,如何做一个缓冲界面,例如有个圆圈在旋转的效果展示

建议使用BackgroundWorker组件,在工具箱中拖到窗口中就可以了。
在DoWork中运行你的耗时的工作
在窗体的load事件中设置RunWorkerAsync启动,并设置一个进度条之类的显示在工作
在RunWorkerCompleted事件中停止进度条显示工作完成
在DoWork中如果直接设置窗口控件的时候注意控件跨线程调用问题需要做InvokeRequired判断,并使用Invoke函数来做控件的调用工作。
参考技术A 创建一个线程,加载数据的时候显示等待界面,数据加载好了再显示出来 参考技术B 创建一个新的线程

以上是关于delphi运行时主界面卡死的主要内容,如果未能解决你的问题,请参考以下文章

c#窗体运行一下然后卡死,无法运行

golang 并发运算时主线程先运行完,子线程运行没结束的问题记录

使用 Java 11 运行 Sonar Scanner 时主版本号错误

unity发布的android游戏有办法让它在后台运行时主线程不停止吗

c# 多线程运行时出现主界面卡死现象如何解决?

DELPHI7在WIN8和WIN10下安装和运行