Skip to content

Conversation

@WSXYT
Copy link
Collaborator

@WSXYT WSXYT commented Jan 3, 2026

把退出的速度优化了,但是重启还是不行()

Copilot AI review requested due to automatic review settings January 3, 2026 15:45
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR optimizes the application's exit and restart processes by improving IPC client management, thread cleanup, and resource release mechanisms. The changes aim to speed up application shutdown, though the PR description notes that restart functionality still has issues.

Key changes:

  • Modified exit and restart flows to use os._exit(0) for faster termination and added comprehensive resource cleanup
  • Changed IPC client thread to daemon mode and improved cleanup logic with explicit disposal calls
  • Enhanced keyboard shortcut cleanup to include global hook removal
  • Updated version comparison logic to properly handle development versions

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 17 comments.

Show a summary per file
File Description
app/view/settings/settings.py Removed QTimer delay for immediate sub-interface creation on initialization
app/view/main/window.py Major refactoring of exit/restart flows with new service stopping methods, shared memory cleanup, and forced exit using os._exit(0)
app/tools/update_utils.py Updated version comparison to return different codes for newer vs failed comparisons; changed to use SPECIAL_VERSION; added update status manager calls
app/common/shortcut/shortcut_manager.py Enhanced cleanup to call keyboard.unhook_all() and added conditional logging
app/common/safety/secure_store.py Improved empty file creation to use proper JSON format with json.dump({}, f) instead of empty bytes
app/common/IPC_URL/csharp_ipc_handler.py Changed client thread to daemon mode, added explicit Dispose calls, reduced sleep interval to 0.1s, and shortened join timeout

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 847 to 866
# 尝试停止更新检查线程
try:
from app.tools import update_utils
if hasattr(update_utils, "update_check_thread") and update_utils.update_check_thread:
if update_utils.update_check_thread.isRunning():
logger.debug("正在停止更新检查线程...")
update_utils.update_check_thread.terminate()
update_utils.update_check_thread.wait(500)
except Exception as e:
logger.debug(f"停止更新检查线程时出错: {e}")

# 停止所有后台服务(音乐、语音等)
self._stop_all_services()

# 停止课前重置定时器
if self.pre_class_reset_timer.isActive():
if hasattr(self, "pre_class_reset_timer") and self.pre_class_reset_timer.isActive():
logger.debug("停止课前重置定时器")
self.pre_class_reset_timer.stop()

self.cleanup_shortcuts()
Copy link

Copilot AI Jan 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The duplicated code for stopping the update check thread, stopping services, stopping the timer, and cleaning up shortcuts in both close_window_secrandom and restart_app methods indicates a maintenance issue. Consider extracting this common cleanup logic into a dedicated method (e.g., _perform_cleanup) to reduce duplication and ensure consistency.

Copilot uses AI. Check for mistakes.
try:
self.client_thread = threading.Thread(
target=self._run_client, daemon=False
target=self._run_client, daemon=True
Copy link

Copilot AI Jan 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing the daemon flag from False to True means the IPC client thread will be forcibly terminated when the main thread exits, potentially leaving the .NET IPC connection in an inconsistent state. While this might speed up exit, it could cause issues with proper resource cleanup in the C# IPC client. Consider keeping daemon=False and fixing the thread's exit logic to respond more quickly to the is_running flag.

Copilot uses AI. Check for mistakes.

while self.is_running:
await asyncio.sleep(1)
await asyncio.sleep(0.1)
Copy link

Copilot AI Jan 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reduced sleep time from 1 second to 0.1 seconds will increase CPU usage by 10x as the loop now wakes up 10 times per second instead of once per second. Unless there's a specific need for more frequent connection checks, consider keeping the longer sleep duration or making it configurable. If faster shutdown response is needed, consider using a threading.Event that can be set to wake the thread immediately.

Suggested change
await asyncio.sleep(0.1)
await asyncio.sleep(1.0)

Copilot uses AI. Check for mistakes.
Comment on lines 634 to 638
if hasattr(update_utils, "update_check_thread") and update_utils.update_check_thread:
if update_utils.update_check_thread.isRunning():
logger.debug("正在停止更新检查线程...")
update_utils.update_check_thread.terminate()
update_utils.update_check_thread.wait(500)
Copy link

Copilot AI Jan 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The global variable update_check_thread is accessed via hasattr check but may not actually be a module-level variable in update_utils. This could silently fail to stop the thread if it's stored elsewhere or named differently. Consider verifying that update_check_thread is indeed a module-level variable in update_utils, or provide a proper API in update_utils to stop the thread.

Suggested change
if hasattr(update_utils, "update_check_thread") and update_utils.update_check_thread:
if update_utils.update_check_thread.isRunning():
logger.debug("正在停止更新检查线程...")
update_utils.update_check_thread.terminate()
update_utils.update_check_thread.wait(500)
thread = getattr(update_utils, "update_check_thread", None)
if thread:
# 确保对象具有线程相关方法,防止错误的全局变量导致静默失败
if hasattr(thread, "isRunning") and hasattr(thread, "terminate") and hasattr(thread, "wait"):
if thread.isRunning():
logger.debug("正在停止更新检查线程...")
thread.terminate()
thread.wait(500)
else:
logger.debug("update_utils.update_check_thread 存在但不是可终止的线程对象,跳过停止操作")
else:
logger.debug("未找到 update_check_thread,全局更新检查线程可能未启动或未在 update_utils 中注册")

Copilot uses AI. Check for mistakes.
Comment on lines 99 to 101
try:
if self.ipc_client and hasattr(self.ipc_client, "Dispose"):
self.ipc_client.Dispose()
Copy link

Copilot AI Jan 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Calling Dispose() on the IPC client from the main thread while the client thread may still be using it creates a race condition. The client thread's asyncio loop might be in the middle of operations on the ipc_client when Dispose() is called from stop_ipc_client(), leading to potential crashes or undefined behavior. Set is_running to False first and wait for the thread to finish before calling Dispose(), or ensure thread-safe disposal.

Copilot uses AI. Check for mistakes.
Comment on lines 670 to 676
# 刷新标准流并强制退出,解决退出挂起及 Python 解释器清理时的崩溃问题
try:
sys.stderr.flush()
sys.stdout.flush()
except Exception:
pass
os._exit(0)
Copy link

Copilot AI Jan 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using os._exit(0) bypasses Python's normal cleanup mechanisms including finally blocks, context managers, and atexit handlers. While this may solve immediate hanging issues, it can leave resources in an inconsistent state and prevent proper cleanup. This is particularly concerning since the PR description mentions restart still doesn't work. Consider using sys.exit(0) instead, which allows Python to perform proper cleanup, or investigate and fix the root cause of the hanging issue.

Suggested change
# 刷新标准流并强制退出,解决退出挂起及 Python 解释器清理时的崩溃问题
try:
sys.stderr.flush()
sys.stdout.flush()
except Exception:
pass
os._exit(0)
# 刷新标准流并请求正常退出,避免跳过 Python 清理流程
try:
sys.stderr.flush()
sys.stdout.flush()
except Exception:
pass
sys.exit(0)

Copilot uses AI. Check for mistakes.
try:
sys.stderr.flush()
sys.stdout.flush()
except Exception:
Copy link

Copilot AI Jan 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'except' clause does nothing but pass and there is no explanatory comment.

Suggested change
except Exception:
except Exception:
# 在强制退出进程前刷新标准流失败可以安全忽略,避免在解释器清理阶段再触发异常

Copilot uses AI. Check for mistakes.
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 10 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 6 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@WSXYT WSXYT closed this Jan 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants