Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exit thread automatically when WPF application closes

I have a main WPF window and one of its controls is a user control that I have created. This user control is an analog clock and contains a thread that update hour, minute and second hands. Initially it wasn't a thread, it was a timer event that updated the hour, minutes and seconds but I have changed it to a thread because the application does some hard work when the user press a start button and then the clock wouldn't update so I changed it to a thread.

Code snippet of WPF window:

     <Window
       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        
xmlns:local="clr-namespace:GParts"
       xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes
       assembly=PresentationFramework.Aero"            
       xmlns:UC="clr-namespace:GParts.UserControls"
       x:Class="GParts.WinMain"
       Title="GParts"    
       WindowState="Maximized"
       Closing="Window_Closing"    
       Icon="/Resources/Calendar-clock.png"
       x:Name="WMain"
     >
     <...>
          <!-- this is my user control -->
          <UC:AnalogClock Grid.Row="1" x:Name="AnalogClock" Background="Transparent"
           Margin="0" Height="Auto" Width="Auto"/>
     <...>
     </Window>

My problem is that when the user exits the application then the thread seems to continue executing. I would like the thread to finish automatically when the main windows closes.

Code snippet of user control constructor:

namespace GParts.UserControls
{
/// <summary>
/// Lógica de interacción para AnalogClock.xaml
/// </summary>
public partial class AnalogClock : UserControl
{
    System.Timers.Timer timer = new System.Timers.Timer(1000);

    public AnalogClock()
    {
        InitializeComponent();

        MDCalendar mdCalendar = new MDCalendar();
        DateTime date = DateTime.Now;
        TimeZone time = TimeZone.CurrentTimeZone;
        TimeSpan difference = time.GetUtcOffset(date);
        uint currentTime = mdCalendar.Time() + (uint)difference.TotalSeconds;

        christianityCalendar.Content = mdCalendar.Date("d/e/Z", currentTime, false);

        // this was before implementing thread
        //timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
        //timer.Enabled = true;

        // The Work to perform 
        ThreadStart start = delegate()
        {

            // With this condition the thread exits when main window closes but
            // despite of this it seems like the thread continues executing after
            // exiting application because in task manager cpu is very  busy
            // 
            while ((this.IsInitialized) && 
                   (this.Dispatcher.HasShutdownFinished== false))
           {

            this.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() =>
            {
                DateTime hora = DateTime.Now;

                secondHand.Angle = hora.Second * 6;
                minuteHand.Angle = hora.Minute * 6;
                hourHand.Angle = (hora.Hour * 30) + (hora.Minute * 0.5);

                DigitalClock.CurrentTime = hora;
            }));
        }
            Console.Write("Quit ok");
        };

        // Create the thread and kick it started!
        new Thread(start).Start();
    }

    // this was before implementing thread
    void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {

        this.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() =>
        {
            DateTime hora = DateTime.Now;

            secondHand.Angle = hora.Second * 6;
            minuteHand.Angle = hora.Minute * 6;
            hourHand.Angle = (hora.Hour * 30) + (hora.Minute * 0.5);

            DigitalClock.CurrentTime = hora;
        }));
    }
 } // end class
 } // end namespace

How can I automatically exit from the thread when the main window closes and then the application exits?

like image 891
toni Avatar asked Dec 18 '22 02:12

toni


1 Answers

Just set the IsBackground property of the Thread to true so it doesn't prevent the process from terminating.

Thread t = new Thread(...) { IsBackground = true };
like image 71
Taylor Leese Avatar answered Jan 03 '23 18:01

Taylor Leese