user9115341
user9115341

Reputation: 1

WPF - Stop Dispatcher Timer with a Button

I have this WPF application. The start button starts a dispatcher timer to perform several sequential tasks. Each task can be time consuming. What I want is to manually stop the dispatcher timer when a current task is taking too long (or actually hangs) In theory, the dispatcher timer ticks every 500 ms and updates the stop button. However, the current task that is being processed locks the dispatcher until the current task completes. And when the current task ends, the stop button is now active and takes effect, but not in real time. Tried different priority levels on the dispatcher timer, with no success. I also tried asynchronous tasks and threads, with no success.

How can I make the stop button have the highest priority to react in the user interface?

        // GLOBAL VARIABLES
        public bool fullStop = false;
        public int numTest = 0;
        public bool testActive = false;
        public string resultIndividualTest = null;
        
        // MAIN
        public MainWindow()
        { 
            InitializeComponent();
        }
        
        // UI COMPONENTS (Start and Stop Buttons), AND METHODS
        private void BStart_Click(object sender, RoutedEventArgs e)
        {
            // init counter
            InitCounterThread();
            // reset global variables
            numTest = 0; fullStop = false;
            // Init DispatcherTimer every 0.5 second with Priority "Render"
            timerTests = new DispatcherTimer(DispatcherPriority.Render); // Render
            timerTests.Interval = new TimeSpan(0, 0, 0, 0, 500); //500 ms
            timerTests.Tick += new EventHandler(TimerTests_Tick);
            timerTests.Start();
        }
        
        private void BStop_Click (object sender, RoutedEventArgs e)
        {
            fullStop = true;
            // stop DispatcherTimer
            timerTests.Stop();
            // stop counter
            StopCounter();
        }
        
        private CancellationTokenSource ts;
        private void TimerTests_Tick(object sender, EventArgs e)
        {
            // SET FOCUS AND REFRESH STOP BUTTON
            BStop.Focus();
            BStop.Refresh();
            // UPDATE LAYOUT UI
            this.UpdateLayout();
                                                        
            if (fullStop == false && testActive == false
            && numTest < MAX && resultIndividualTest == null){
                // next test (FROM 1 TO MAX)
                numTest++;
                // now test will be activated until it finishes …
                testActive = true;
                ts = new CancellationTokenSource();
                CancellationToken ct = ts.Token;
                Task.Factory.StartNew( () => this.Dispatcher.Invoke( 
                () => resultIndividualTest = BTestClick(numTest)), ct);            
            }
            else if (resultIndividualTest != null){
                // individual test (task) has finished with result no null
                resultIndividualTest = null;
                testActive = false;
                ts.Cancel();
            }
            else if (numTest >= MAX || fullStop == true){
                // stop DispatcherTimer
                timerTests.Stop();
                // stop counter
                StopCounter();
            }    
            else{
                // the timer continues …
            }
        }
        
        public string BTestClick(int numTest){
            /* This method does an individual test */
            string result = ""; bool r = false;
            If (numTest == 1) {r = routine1();}
            If (numTest == 2) {r = routine2();}
            … … …
            If (r == true) {result = "OK";}
            else {result = "ERROR"}
            return result;
        }
        
        public bool routine1(){
            bool result = false;
            // ... ... this may take very long (from 5 to 40 seconds)
            return result;
        }
        
        public bool routine2(){
            bool result = false;
            // ... ... this may take very long (from 5 to 40 seconds)
            return result;
        }

Upvotes: 0

Views: 20

Answers (0)

Related Questions