Delphi线程Suspend为什么停不下来?GetLastError获取的错误不能被try except捕获吗

xumenger 2016-05-06 11:07:35
GetLastError

GetLastError是获取调用系统API出现的报错信息
这种类型的错误能够被 try except 方式的异常机制捕获吗?

线程

使用Delphi实现的一个线程,代码如下
GetLastError获取的错误码是2,并没有捕获异常,但是线程持续运行,说明suspend没有起作用
另外,线程反复输出如下信息,并没有报错,说明压缩成功,走到suspend方法调用的代码行



正在压缩文件,请稍候...
压缩文件完成
GetLastError:2
正在压缩文件,请稍候...
压缩文件完成
GetLastError:2
正在压缩文件,请稍候...
压缩文件完成
GetLastError:2
....



为什么线程没有正常suspend而停止运行,反而是一直循环,根本停不下来


procedure TZipTask.Execute;
var
bSuccess: Boolean;
index: Integer;
iError: Integer;
begin
while not Terminated do
begin
try
index := GetCurrentThreadId;
SendMsg('正在压缩文件,请稍候...');
......//这里调用封装的一个压缩文件的API
if bSuccess then
SendMsg('压缩文件完成')
else
SendMsg('停止压缩文件');
except
on e:Exception do
begin
SendMsg('压缩文件出错' + E.Message);
end;
end;
bComplete := True;
Self.Suspend;
iError := GetLastError;
SendMsg('GetLastError:' + IntToStr(iError));
end;
end;
...全文
827 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
xumenger 2016-05-22
  • 打赏
  • 举报
回复
经过最终的排查,是因为在Windows Server2003的机器上,将进程设置为【兼容Windows95】方式运行 导致在这种情况下调用Windows的API方法SuspendThread无效 这个可以自己简单的实现一个程序进行验证!
SVIP_ 2016-05-10
  • 打赏
  • 举报
回复
是吃了炫迈吗
  • 打赏
  • 举报
回复
“设置Resume的地方只有一个”不代表Resume的执行次数和执行次序和Suspend是匹配的,你应该log Suspend和Resume的每次执行时间。
xumenger 2016-05-09
  • 打赏
  • 举报
回复
试了在压缩日志的地方SetLastError(2),但是线程可以正常suspend 检查代码程序设置Resume的地方只有一个,而且在客户现场排查的时候确认持续运行输出信息的线程就是一个线程
  • 打赏
  • 举报
回复
1. GetLastError只是返回当前线程保存的最后一次错误代码(由调用SetLastError设置),错误代码不代表出现异常,如果生成错误代码的函数里没有throw,就只是安静地返回一个错误代码。 2. 因为大部分API函数都设置错误代码,所以你把GetLastError写在这里是错误的: Self.Suspend; iError := GetLastError; Suspend在windows上的实现是调用API SuspendThread或者Wow64SuspendThread,所以你这里GetLastError的是它的SetLastError,而不是你的压缩函数设置的错误代码(如果它确实有调用SetLastError),另外TThread.Suspend内部也可能调用了GetLastError。 3. "Suspend为什么停不下来",估计是因为Suspend和Resume不匹配造成的,可能你调用Resume或者Start的次数多于Suspend,在windows上线程挂起和恢复是基于挂起计数的,SuspendThread增加计数,ResumeThread减少计数,计数为0线程运行,大于0则挂起。
xumenger 2016-05-07
  • 打赏
  • 举报
回复
Delphi的版本是6,现在的现象就是持续运行无法停止线程
hongss 2016-05-07
  • 打赏
  • 举报
回复
现在都用 MyThread.Suspended:= true; 这样的吧~~
看那山瞧那水 2016-05-07
  • 打赏
  • 举报
回复
while not Terminated do 一般不建议这样判断 suspend d7以后已经废弃了,不建议用。
xumenger 2016-05-07
  • 打赏
  • 举报
回复
现在的情况是,只有在客户的那一台机器上有问题,我们内部没有办法复现这个问题,之前是我在客户现场做的一些修改和尝试 但是因为现在已经回来了,想到的一些场景也没办法再去改代码给现场进行尝试了 如果GetLastError获取的错误码2,是在压缩文件的代码段中出现的问题,是不是因为GetLastError式的错误无法被普通的try except捕获?为什么? 如果GetLastError获取的错误码2,是在调用suspend的时候出现的,就可以解释为什么线程无法停止了,但是感觉不太可能,毕竟错误码2表示“系统找不到指定的文件”,看这个错像是在压缩文件的地方报出来的!
lyhoo163 2016-05-07
  • 打赏
  • 举报
回复

procedure TZipTask.Execute;
var
  bSuccess: Boolean;
  index: Integer;
  iError: Integer;
begin
  try
    index := GetCurrentThreadId;
    SendMsg('正在压缩文件,请稍候...');
    ......//这里调用封装的一个压缩文件的API
    if bSuccess then
      SendMsg('压缩文件完成')
    else
      SendMsg('停止压缩文件');
  except
    on e:Exception do
      SendMsg('压缩文件出错' + E.Message);
  end;
  bComplete := True;
  Self.Suspend;
  iError := GetLastError;
  SendMsg('GetLastError:' + IntToStr(iError));
end;
这样,试试。
mdejtod 2016-05-07
  • 打赏
  • 举报
回复
在线程外部挂起
内容概要:本文系统阐述了面向综合能源系统的算力-电力-热力联合优化调度策略,并提供基于Matlab的完整代码实现。研究围绕多能源耦合系统中的协同优化问题展开,深度融合计算资源调度与能源系统运行,构建包含算力任务分配、电力供需平衡与热力网络约束的联合优化模型。重点解决了高比例可再生能源接入下的不确定性挑战,采用分布鲁棒优化、粒子群优化(PSO)等先进算法提升调度方案的经济性、可靠性与灵活性。同时引入隐私保护机制与联邦学习架构,保障多主体间数据安全协同。配套资源涵盖详细的仿真代码、案例数据及算法工具包(如YALMIP),支持模型快速复现与扩展研究,适用于复杂能源系统建模与智能算法验证。; 适合人群:具备电力系统、热力工程、自动化或运筹优化等相关背景,熟悉Matlab/Simulink仿真环境,从事能源系统规划与运行研究的研究生、博士生及科研人员;特别适合开展综合能源系统优化、智能调度算法开发、SCI论文复现与科研创新的研究者。; 使用场景及目标:①构建算力-电力-热力多能流协同调度模型并进行仿真分析;②研究含风电等不确定性源的鲁棒优化调度方法;③应用PSO、分布鲁棒优化等智能算法解决实际能源调度问题;④作为高水平期刊论文复现、算法对比与科研成果转化的技术支撑; 阅读建议:建议结合公众号“荔枝科研社”发布的网盘资源,按模块顺序学习模型构建与算法实现细节,重点关注目标函数设计、约束条件建模及求解器调用逻辑,通过调试代码与修改参数深化理解,并开展二次开发以拓展应用场景。

1,184

社区成员

发帖
与我相关
我的任务
社区描述
Delphi Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧