fix: 重试计时不准,修复Tkinter after()延迟问题\n\n根因:Tkinter的after()在窗口非活动时会延迟触发,\n导致实际重试间隔不是准确的5秒,可能变成十几秒甚至更长。\n\n修复:记录目标重试时间,执行前验证是否真的到了时机。\n若未到,重新调度;若已到,执行重试。\n这样确保重试间隔是实打实的5秒,不是虚的5秒。
This commit is contained in:
@@ -1182,14 +1182,27 @@ class MsgBotApp(ctk.CTk):
|
||||
def _execute_reply(self, data: dict):
|
||||
"""主线程执行自动回复发送。加上发送锁防止监控轮询干扰。
|
||||
自动重试:失败后延缓5秒重试,连续3次失败视为用户接管,退避本轮。
|
||||
⭐ 2026-08-20 修复:记录目标重试时间,防止Tkinter after()延迟导致计时不准。
|
||||
"""
|
||||
import time as _time
|
||||
platform = data["platform"]
|
||||
answer = data["answer"]
|
||||
sender = data.get("sender")
|
||||
msg = data.get("msg", "")
|
||||
max_retries = 3
|
||||
retry_delay = 5 # 秒
|
||||
attempt = data.get("_attempt", 0) # ⭐ 主线程异步重试计数(不阻塞GUI)
|
||||
attempt = data.get("_attempt", 0)
|
||||
|
||||
# ⭐ 验证重试时机:若目标时间未到,重新调度(防止after()延迟)
|
||||
if attempt > 0:
|
||||
_retry_at = data.get("_retry_at", 0)
|
||||
_now = _time.time()
|
||||
if _now < _retry_at:
|
||||
_remaining = int((_retry_at - _now) * 1000)
|
||||
logger.debug(f"[{platform}] 重试时机未到({_remaining}ms),重新调度")
|
||||
data["_retry_at"] = _retry_at
|
||||
self.after(_remaining, lambda d=data: self._execute_reply(d))
|
||||
return
|
||||
|
||||
# ⭐ 发送前强制检查时间戳:≤300秒则发送,≥300秒则丢弃
|
||||
msg_age = self._check_message_freshness(msg)
|
||||
@@ -1213,11 +1226,14 @@ class MsgBotApp(ctk.CTk):
|
||||
return # 成功直接退出
|
||||
else:
|
||||
if attempt < max_retries - 1:
|
||||
# ⭐ 记录目标重试时间,确保重试间隔准确
|
||||
_retry_at = _time.time() + retry_delay
|
||||
data["_attempt"] = attempt + 1
|
||||
data["_retry_at"] = _retry_at
|
||||
self._log(f"[{platform}] ⚠ 自动回复发送失败,{retry_delay}秒后重试({attempt+1}/{max_retries})")
|
||||
# ⭐ 2026-08-17 修复GUI冻结:原实现主线程 time.sleep(5) ×3 = 界面冻结15秒+
|
||||
# 窗口不前置时 _paste_and_send 必失败,用户跟踪日志时 GUI 无响应。
|
||||
# 改为 after() 异步重试:主线程立即返回,5秒后再执行,界面保持流畅。
|
||||
data["_attempt"] = attempt + 1
|
||||
self.after(int(retry_delay * 1000), lambda d=data: self._execute_reply(d))
|
||||
else:
|
||||
self._log(f"[{platform}] ⚠ 自动回复发送失败(连续{max_retries}次),用户可能在接管,本轮跳过")
|
||||
|
||||
Reference in New Issue
Block a user