1. 为什么3DMark测试需要自动化监控如果你经常用3DMark做显卡稳定性测试肯定遇到过这种情况半夜跑着跑着突然闪退早上起来发现只测了一半或者测试过程中程序卡死需要手动重启。这种情况在批量测试或者长时间压力测试时尤其让人头疼。我在做显卡兼容性测试时经常需要连续跑几十轮3DMark。最开始都是手动操作后来实在受不了半夜爬起来重启测试就琢磨着用Delphi写了个守护程序。这个程序的核心功能很简单实时监控3DMark进程状态发现异常就自动重启测试完全不需要人工干预。Windows系统提供了完善的进程管理API通过CreateToolhelp32Snapshot可以获取当前所有进程的快照Process32First和Process32Next能遍历这些进程信息。当检测到3DMark进程无响应或者意外退出时TerminateProcess可以强制结束残留进程CreateProcess又能重新启动测试。配合定时器检测就形成了一个完整的自动化测试闭环。2. 构建监控系统的关键技术点2.1 进程快照与状态检测Delphi调用Windows API获取进程信息非常方便。核心代码是这样的function TForm1.CheckProcessRunning(ExeName: string): Boolean; var hSnapshot: THandle; pe32: TProcessEntry32; begin Result : False; hSnapshot : CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if hSnapshot INVALID_HANDLE_VALUE then try pe32.dwSize : SizeOf(pe32); if Process32First(hSnapshot, pe32) then repeat if SameText(pe32.szExeFile, ExeName) then begin Result : True; Break; end; until not Process32Next(hSnapshot, pe32); finally CloseHandle(hSnapshot); end; end;这段代码会遍历系统所有进程检查目标程序是否在运行。我在实际使用中发现单纯检查进程存在还不够还需要检测程序是否响应。可以配合GetProcessTimes函数获取进程CPU时间如果长时间没有变化就说明可能卡死了。2.2 超时检测与自动恢复定时器是另一个关键组件。我设置了一个Timer控件每隔30秒检查一次procedure TForm1.Timer1Timer(Sender: TObject); begin if not CheckProcessRunning(3DMark.exe) then begin // 记录日志 Memo1.Lines.Add(FormatDateTime(yyyy-mm-dd hh:nn:ss, Now) 3DMark进程丢失正在重启...); // 先清理可能残留的进程 EndProcess(3DMark.exe); // 重新启动测试 Run3DMarkTest; end else if IsProcessHung(3DMark.exe) then begin Memo1.Lines.Add(FormatDateTime(yyyy-mm-dd hh:nn:ss, Now) 检测到3DMark无响应正在恢复...); EndProcess(3DMark.exe); Run3DMarkTest; end; end;这里有个小技巧重启前最好加个短暂延迟我一般设为5秒避免系统资源释放不及时导致启动失败。3. 完整实现方案详解3.1 程序架构设计整个守护程序主要包含三个模块监控模块定时检查3DMark进程状态恢复模块处理异常情况并重启测试日志模块记录所有操作和异常事件我建议使用INI文件来保存配置比如测试参数、超时阈值等。这样不用重新编译程序就能调整设置// 读取配置 IniFile : TIniFile.Create(Config.ini); try FTimeout : IniFile.ReadInteger(Settings, Timeout, 30); FTestCommand : IniFile.ReadString(Settings, CommandLine, 3DMarkCmd.exe --definitiontime_spy.3dmdef); finally IniFile.Free; end;3.2 异常处理细节在实际测试中我发现几种常见异常情况进程崩溃直接消失监控发现进程不存在程序卡死进程还在但不响应测试超时单次测试耗时远超预期针对这些情况我分别写了处理函数procedure HandleProcessCrash; begin Log(3DMark进程崩溃); Cleanup; // 清理临时文件等 RestartTest; end; procedure HandleProcessHung; begin Log(检测到3DMark无响应); ForceTerminate; // 强制终止 Sleep(5000); // 等待资源释放 RestartTest; end; procedure HandleTestTimeout; begin Log(测试超时强制重启); ForceTerminate; Cleanup; RestartTest; end;4. 实战经验与优化建议4.1 性能优化技巧长时间运行监控程序要注意资源占用问题。我踩过几个坑进程快照频率最初设置每秒检查一次结果CPU占用很高。后来调整为30秒一次既保证及时性又不影响性能。日志文件管理如果不加控制日志文件会越来越大。我的做法是每天新建一个日志文件超过7天的自动删除单个文件超过10MB就压缩归档异常重试机制网络波动可能导致测试启动失败我增加了重试逻辑RetryCount : 0; while RetryCount 3 do begin if StartTest then Break else begin Inc(RetryCount); Sleep(5000); end; end; if RetryCount 3 then SendAlert(3DMark启动失败请检查!);4.2 扩展功能建议基础功能实现后可以考虑添加这些实用功能邮件/短信报警测试连续失败时通知管理员测试结果自动收集解析3DMark生成的日志文件多显卡支持轮流测试不同显卡远程监控通过HTTP接口查看测试状态我在项目中集成邮件报警功能后半夜再也不用起床检查测试状态了。核心代码很简单procedure SendAlert(const Msg: string); var SMTP: TIdSMTP; Email: TIdMessage; begin SMTP : TIdSMTP.Create(nil); Email : TIdMessage.Create(nil); try SMTP.Host : smtp.example.com; SMTP.Username : alertsexample.com; SMTP.Password : password; Email.From.Address : alertsexample.com; Email.Recipients.Add.Address : adminexample.com; Email.Subject : 3DMark测试异常报警; Email.Body.Text : Msg; SMTP.Connect; SMTP.Send(Email); SMTP.Disconnect; finally SMTP.Free; Email.Free; end; end;这套系统在我司已经稳定运行两年多累计完成超过5000次自动化测试将人工干预次数降到了几乎为零。最关键的3DMark闪退问题完全得到解决测试效率提升了近10倍。
[Delphi]:构建自动化监控与恢复系统,根治3DMark测试中的闪退与无响应
发布时间:2026/6/30 15:35:24
1. 为什么3DMark测试需要自动化监控如果你经常用3DMark做显卡稳定性测试肯定遇到过这种情况半夜跑着跑着突然闪退早上起来发现只测了一半或者测试过程中程序卡死需要手动重启。这种情况在批量测试或者长时间压力测试时尤其让人头疼。我在做显卡兼容性测试时经常需要连续跑几十轮3DMark。最开始都是手动操作后来实在受不了半夜爬起来重启测试就琢磨着用Delphi写了个守护程序。这个程序的核心功能很简单实时监控3DMark进程状态发现异常就自动重启测试完全不需要人工干预。Windows系统提供了完善的进程管理API通过CreateToolhelp32Snapshot可以获取当前所有进程的快照Process32First和Process32Next能遍历这些进程信息。当检测到3DMark进程无响应或者意外退出时TerminateProcess可以强制结束残留进程CreateProcess又能重新启动测试。配合定时器检测就形成了一个完整的自动化测试闭环。2. 构建监控系统的关键技术点2.1 进程快照与状态检测Delphi调用Windows API获取进程信息非常方便。核心代码是这样的function TForm1.CheckProcessRunning(ExeName: string): Boolean; var hSnapshot: THandle; pe32: TProcessEntry32; begin Result : False; hSnapshot : CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if hSnapshot INVALID_HANDLE_VALUE then try pe32.dwSize : SizeOf(pe32); if Process32First(hSnapshot, pe32) then repeat if SameText(pe32.szExeFile, ExeName) then begin Result : True; Break; end; until not Process32Next(hSnapshot, pe32); finally CloseHandle(hSnapshot); end; end;这段代码会遍历系统所有进程检查目标程序是否在运行。我在实际使用中发现单纯检查进程存在还不够还需要检测程序是否响应。可以配合GetProcessTimes函数获取进程CPU时间如果长时间没有变化就说明可能卡死了。2.2 超时检测与自动恢复定时器是另一个关键组件。我设置了一个Timer控件每隔30秒检查一次procedure TForm1.Timer1Timer(Sender: TObject); begin if not CheckProcessRunning(3DMark.exe) then begin // 记录日志 Memo1.Lines.Add(FormatDateTime(yyyy-mm-dd hh:nn:ss, Now) 3DMark进程丢失正在重启...); // 先清理可能残留的进程 EndProcess(3DMark.exe); // 重新启动测试 Run3DMarkTest; end else if IsProcessHung(3DMark.exe) then begin Memo1.Lines.Add(FormatDateTime(yyyy-mm-dd hh:nn:ss, Now) 检测到3DMark无响应正在恢复...); EndProcess(3DMark.exe); Run3DMarkTest; end; end;这里有个小技巧重启前最好加个短暂延迟我一般设为5秒避免系统资源释放不及时导致启动失败。3. 完整实现方案详解3.1 程序架构设计整个守护程序主要包含三个模块监控模块定时检查3DMark进程状态恢复模块处理异常情况并重启测试日志模块记录所有操作和异常事件我建议使用INI文件来保存配置比如测试参数、超时阈值等。这样不用重新编译程序就能调整设置// 读取配置 IniFile : TIniFile.Create(Config.ini); try FTimeout : IniFile.ReadInteger(Settings, Timeout, 30); FTestCommand : IniFile.ReadString(Settings, CommandLine, 3DMarkCmd.exe --definitiontime_spy.3dmdef); finally IniFile.Free; end;3.2 异常处理细节在实际测试中我发现几种常见异常情况进程崩溃直接消失监控发现进程不存在程序卡死进程还在但不响应测试超时单次测试耗时远超预期针对这些情况我分别写了处理函数procedure HandleProcessCrash; begin Log(3DMark进程崩溃); Cleanup; // 清理临时文件等 RestartTest; end; procedure HandleProcessHung; begin Log(检测到3DMark无响应); ForceTerminate; // 强制终止 Sleep(5000); // 等待资源释放 RestartTest; end; procedure HandleTestTimeout; begin Log(测试超时强制重启); ForceTerminate; Cleanup; RestartTest; end;4. 实战经验与优化建议4.1 性能优化技巧长时间运行监控程序要注意资源占用问题。我踩过几个坑进程快照频率最初设置每秒检查一次结果CPU占用很高。后来调整为30秒一次既保证及时性又不影响性能。日志文件管理如果不加控制日志文件会越来越大。我的做法是每天新建一个日志文件超过7天的自动删除单个文件超过10MB就压缩归档异常重试机制网络波动可能导致测试启动失败我增加了重试逻辑RetryCount : 0; while RetryCount 3 do begin if StartTest then Break else begin Inc(RetryCount); Sleep(5000); end; end; if RetryCount 3 then SendAlert(3DMark启动失败请检查!);4.2 扩展功能建议基础功能实现后可以考虑添加这些实用功能邮件/短信报警测试连续失败时通知管理员测试结果自动收集解析3DMark生成的日志文件多显卡支持轮流测试不同显卡远程监控通过HTTP接口查看测试状态我在项目中集成邮件报警功能后半夜再也不用起床检查测试状态了。核心代码很简单procedure SendAlert(const Msg: string); var SMTP: TIdSMTP; Email: TIdMessage; begin SMTP : TIdSMTP.Create(nil); Email : TIdMessage.Create(nil); try SMTP.Host : smtp.example.com; SMTP.Username : alertsexample.com; SMTP.Password : password; Email.From.Address : alertsexample.com; Email.Recipients.Add.Address : adminexample.com; Email.Subject : 3DMark测试异常报警; Email.Body.Text : Msg; SMTP.Connect; SMTP.Send(Email); SMTP.Disconnect; finally SMTP.Free; Email.Free; end; end;这套系统在我司已经稳定运行两年多累计完成超过5000次自动化测试将人工干预次数降到了几乎为零。最关键的3DMark闪退问题完全得到解决测试效率提升了近10倍。