internal class BlockDetector { bool _isBusy; private const int FreezeTimeLimit = 400; private readonly DispatcherTimer _foregroundTimer; private readonly Timer _backgroundTimer; private DateTime _lastForegroundTimerTickTime; public event Action UIBlocked; public event Action UIReleased; public BlockDetector() { _foregroundTimer = new DispatcherTimer{ Interval = TimeSpan.FromMilliseconds(FreezeTimeLimit / 2) }; _foregroundTimer.Tick += ForegroundTimerTick; _backgroundTimer = new Timer(BackgroundTimerTick, null, FreezeTimeLimit, Timeout.Infinite); } private void BackgroundTimerTick(object someObject) { var totalMilliseconds = (DateTime.Now - _lastForegroundTimerTickTime).TotalMilliseconds; if (totalMilliseconds > FreezeTimeLimit && _isBusy == false) { _isBusy = true; Dispatcher.CurrentDispatcher.Invoke(() => UIBlocked()); ; } else { if (totalMilliseconds < FreezeTimeLimit && _isBusy) { _isBusy = false; Dispatcher.CurrentDispatcher.Invoke(() => UIReleased()); ; } } _backgroundTimer.Change(FreezeTimeLimit, Timeout.Infinite); } private void ForegroundTimerTick(object sender, EventArgs e) { _lastForegroundTimerTickTime = DateTime.Now; } public void Start() { _foregroundTimer.Start(); } public void Stop() { _foregroundTimer.Stop(); _backgroundTimer.Dispose(); } }
private void ShowNotify() { var thread = new Thread((ThreadStart)delegate { // _threadDispacher = Dispatcher.CurrentDispatcher; SynchronizationContext.SetSynchronizationContext(new DispatcherSynchronizationContext(_threadDispacher)); // _notifyWindow = _createWindowDelegate.Invoke(); // _notifyWindow.Closed += (sender,e) => _threadDispacher.BeginInvokeShutdown(DispatcherPriority.Background); _notifyWindow.Show(); // Windows Dispatcher.Run(); }); thread.SetApartmentState(ApartmentState.STA); thread.IsBackground = true; thread.Start(); }
Source: https://habr.com/ru/post/260029/
All Articles