From 19c7c7cf028903b2a5cb7157aa209772b6cf6af6 Mon Sep 17 00:00:00 2001 From: lvjunjie Date: Thu, 10 Sep 2026 11:03:50 +0800 Subject: [PATCH] =?UTF-8?q?fix(nmNum):=20=E4=BF=AE=E5=A4=8D=20LM=20?= =?UTF-8?q?=E7=AD=89=E5=BE=85=E6=B1=82=E8=A7=A3=E6=97=B6=E5=81=9C=E6=AD=A2?= =?UTF-8?q?=E6=8C=89=E9=92=AE=E6=97=A0=E6=B3=95=E5=93=8D=E5=BA=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 等待 DLL 求解期间处理鼠标和键盘事件,使停止按钮能够响应 - 移除停止函数中的阻塞等待,登记停止请求后立即返回 - 用户停止改用协作取消接口,等待 DLL 返回后丢弃本次结果,避免强制终止线程破坏内部锁 --- .../nmCalculation/nmCalculationAutoFitLM.cpp | 28 +++++++++---------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/Src/nmNum/nmCalculation/nmCalculationAutoFitLM.cpp b/Src/nmNum/nmCalculation/nmCalculationAutoFitLM.cpp index c3f3c41..637590c 100644 --- a/Src/nmNum/nmCalculation/nmCalculationAutoFitLM.cpp +++ b/Src/nmNum/nmCalculation/nmCalculationAutoFitLM.cpp @@ -574,16 +574,7 @@ void nmCalculationAutoFitLM::stopFitting() emit logMessageGenerated(tr("Gracefully stopping LM automatic fitting...")); m_shouldStop = true; - // 给当前评价一个短暂的自然退出时间。若仍在运行, - // runSolverDll() 会在下一个等待周期检查 m_shouldStop 并结束任务。 - int waitCount = 0; - - while(m_evaluationInProgress > 0 && waitCount < 30) { - QApplication::processEvents(QEventLoop::ExcludeUserInputEvents, 50); - msleep(50); - waitCount++; - } - + // 此槽由求解等待循环派发,必须立即返回,外层循环才能转发取消请求。 if(m_evaluationInProgress > 0) { emit logMessageGenerated(tr("Waiting for current solver evaluation to stop...")); } @@ -3919,7 +3910,7 @@ QVector> nmCalculationAutoFitLM::runSolverDll() // 异步执行 DLL 任务。循环等待期间持续 processEvents,保证界面不会完全卡死。 dllTask->start(); - // 等待完成。最大等待 1 小时,适配大模型慢算;用户停止时会 terminate。 + // 等待完成。最大等待 1 小时;用户停止使用任务已有的协作取消接口。 const int maxWait = 3600000; // 1h超时 const int checkInterval = 50; QTime waitTimer; @@ -3933,12 +3924,12 @@ QVector> nmCalculationAutoFitLM::runSolverDll() break; } - QApplication::processEvents(QEventLoop::ExcludeUserInputEvents, checkInterval); + // 等待期间也派发鼠标、键盘事件,让停止按钮能及时登记请求。 + QApplication::processEvents(QEventLoop::AllEvents, checkInterval); if(m_shouldStop) { - DEBUG_OUT("DLL solver task terminated by user"); - dllTask->terminate(); - break; + // DLL 没有中断接口,返回后丢弃结果,避免强制终止破坏其内部锁。 + dllTask->requestCancel(); } } @@ -3957,6 +3948,13 @@ QVector> nmCalculationAutoFitLM::runSolverDll() // 线程结束后检查真实执行结果,防止失败时复用上一粒子的旧曲线。 dllTask->wait(); + if(m_shouldStop) { + DEBUG_OUT("DLL solver evaluation cancelled by user"); + delete dllTask; + dllTask = nullptr; + --m_evaluationInProgress; + return result; + } if(!dllTask->wasSuccessful()) { DEBUG_OUT("DLL solver task reported failure"); delete dllTask;