using System; using System.IO; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using DualScreenDemo.Shared; public class WatchDog { private Func getVideoStatus; private Func isApplicationResponsive; private Thread watchdogThread; private bool running = false; private double lastPosition = -1; private int freezeCounter = 0; public WatchDog(Func getVideoPositionFunc, Func isAppResponsiveFunc) { getVideoStatus = getVideoPositionFunc; isApplicationResponsive = isAppResponsiveFunc; } public void Start() { running = true; watchdogThread = new Thread(Run); watchdogThread.IsBackground = true; watchdogThread.Start(); } public void Stop() { running = false; watchdogThread?.Join(); } private void Run() { while (running) { var status = getVideoStatus(); // 改用 getVideoStatus 取得完整狀態 bool responsive = isApplicationResponsive(); if (!status.IsGraphOk) { Log($"影片圖表異常: {status.LastError}"); } else if(status.PlayState != "Paused") { double currentPosition = status.PositionSeconds; if (Math.Abs(currentPosition - lastPosition) < 0.001) { freezeCounter++; if (freezeCounter >= 3) { Log($"影片疑似卡死(3次位置沒變):位置={currentPosition:F2}秒,播放狀態={status.PlayState}"); freezeCounter = 0; // 記得 reset } } else { freezeCounter = 0; } lastPosition = currentPosition; } if (!responsive) { Log("UI 疑似卡死(Invoke 失敗)"); } Thread.Sleep(5000); } } private void Log(string message) { string logFilePath = Path.Combine("txt", "watchdog_log.txt"); File.AppendAllText(logFilePath, $"{DateTime.Now}: {message}{Environment.NewLine}"); } }