Concept of Multithreading in Windows


Isn't it fun,

to instantly listen to a blog on the go? PLAY !

 
 

Multithreading-Windows

What is Thread?

A thread is a separate execution path within a program and Window is a multithreading operating system that manages threads. In WPF when we execute a program each program is assigned a single thread by default.

There are many benefits to use multithreading in Windows applications. Let’s see the benefits of Multithreading in Windows applications.

  1. Improve performance and concurrency
  2. Simplified coding of remote procedure calls and conversation
  3. Simultaneous access to multiple applications
  4. Reduce the number of required servers

There are also some disadvantages to use multithreading in the Window application.

  1. Writing a line of code is difficult
  2. Debugging the program is difficult
  3. Managing concurrency is difficult

Now, let’s start the coding part.

Step: 1

Create a Window application. And here we need to create classes for creating windows. So first create one folder and inside the folder add a class file and add the below code.

CustomDialogWindow.cs
usingSystem.ComponentModel;
usingSystem.Windows;
usingSystem.Windows.Input;

namespaceOtherThreadWindow.BaseWindow
{
    publicclassCustomDialogWindow : Window, INotifyPropertyChanged
    {
     publiceventPropertyChangedEventHandlerPropertyChanged;

        publicCustomDialogWindow()
        {
           this.CommandBindings.Add(newCommandBinding(SystemCommands.CloseWindowCommand, OnCloseWindow));

           DataContext = this;
        }

        publicvoidOnPropertyChanged(stringpropertyName)
        {
           PropertyChanged?.Invoke(this, newPropertyChangedEventArgs(propertyName));
        }

         publicvirtualvoidOnDragWindow(object sender, MouseButtonEventArgs e)
        {
           if (e.LeftButton != MouseButtonState.Pressed)
           return;

           else
            {
                DragMove();
            }
        }

        publicvoidOnCloseWindow(object sender, ExecutedRoutedEventArgs e)
        {
                this.Close();
        }
    }
}

This class is used for a second dialog window.



Step: 2

Now, we can add a class for a custom window.

CustomWindow.cs
using System;
usingSystem.Windows;
usingSystem.Windows.Input;
using Cursors = System.Windows.Input.Cursors;
usingMouseEventArgs = System.Windows.Input.MouseEventArgs;

namespaceOtherThreadWindow.BaseWindow
{
    publicclassCustomWindow :CustomDialogWindow
    {
       private Visibility _normalizeWindowBtnVisibility;
       private Visibility _maximizeWindowBtnVisibility;

       public Visibility MaximizeWindowBtnVisibility
       {
          get{ return _maximizeWindowBtnVisibility; }
          set
            {
            if (_maximizeWindowBtnVisibility != value)
                {
                    _maximizeWindowBtnVisibility = value;
                    OnPropertyChanged(nameof(MaximizeWindowBtnVisibility));
                }
            }
        }
       public Visibility NormalizeWindowBtnVisibility
        {
          get{ return _normalizeWindowBtnVisibility; }
          set
            {
               if (_normalizeWindowBtnVisibility != value)
                {
                    _normalizeWindowBtnVisibility = value;
                    OnPropertyChanged(nameof(NormalizeWindowBtnVisibility));
                }
            }
        }
        publicCustomWindow()
        {
             this.SourceInitialized += Window_OnSourceInitialized;
             this.PreviewMouseMove += Window_OnPreviewMouseMove;
        }

        publicvoidWindow_OnSourceInitialized(object sender, EventArgs e)
        {
           if (this.WindowState == WindowState.Maximized)
            {
               MaximizeWindowBtnVisibility = Visibility.Collapsed;
               NormalizeWindowBtnVisibility = Visibility.Visible;
            }
            elseif (this.WindowState == WindowState.Normal)
            {
               MaximizeWindowBtnVisibility = Visibility.Visible;
               NormalizeWindowBtnVisibility = Visibility.Collapsed;
            }
        }

        publicvoidWindow_OnPreviewMouseMove(object sender, MouseEventArgs e)
        {
           if (e.LeftButton != MouseButtonState.Pressed)
                Cursor = Cursors.Arrow;
        }

        publicoverridevoidOnDragWindow(object sender, MouseButtonEventArgs e)
        {
              if (e.ClickCount == 2)
              return;

              if (e.LeftButton != MouseButtonState.Pressed)
              return;

            {
              DragMove();
            }
        }

        publicvoidButtonMinimize_OnClick(object sender, RoutedEventArgs e)
        {
           WindowState = WindowState.Minimized;
        }

        publicvoidButtonMaximize_OnClick(object sender, RoutedEventArgs e)
        {
           WindowState = WindowState.Maximized;
           ShowRestoreDownButton();
        }

        publicvoidShowRestoreDownButton()
        {
           MaximizeWindowBtnVisibility = Visibility.Collapsed;
           NormalizeWindowBtnVisibility = Visibility.Visible;
        }

        publicvoidShowMaximumWindowButton()
        {
           NormalizeWindowBtnVisibility = Visibility.Collapsed;
           MaximizeWindowBtnVisibility = Visibility.Visible;
        }

        publicvoidButtonRestoreDown_OnClick(object sender, RoutedEventArgs e)
        {
           ShowMaximumWindowButton();
        }

        privatevoidSwitchState()
        {
        switch (WindowState)
            {
               caseWindowState.Normal:
                    {
                        WindowState = WindowState.Maximized;
                        ShowRestoreDownButton();
                        break;
                    }
              caseWindowState.Maximized:
                    {
                        ShowMaximumWindowButton();
                        break;
                    }
            }
        }

        publicvoidButton_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
             if ((ResizeMode == ResizeMode.CanResize) ||
             (ResizeMode == ResizeMode.CanResizeWithGrip))
             {
                   SwitchState();
                   return;
            }
        }

        ~CustomWindow()
        {
              this.SourceInitialized -= Window_OnSourceInitialized;
              this.PreviewMouseMove -= Window_OnPreviewMouseMove;
        }
    }
}

Step: 3

OtherthreadwindowBase.cs
using System;
usingSystem.Runtime.InteropServices;
usingSystem.Windows;
usingSystem.Windows.Interop;

namespaceOtherThreadWindow.BaseWindow
{
    publicclassOtherThreadWindowBase : Window, IDisposable
    {
        publicvoidDispose()
        {
        try
            {
                GC.Collect();
                GC.WaitForPendingFinalizers();
            }
        catch (Exception ex)
            {

            }
        }
    }
}

One Stop Solution for WPF Application Development ?

Your Search ends here.


Step: 4

Now, we can write a code for animation. For this, you need to add one content page. On the page add the below code. And add one GIF in the resources folder.

EkgWindow.xaml

Here, we can add GIF for animation. And inherit base class on code-behind.
 


<basewindow:otherthreadwindowbase allowstransparency="True" background="#000000" mc:ignorable="d" showintaskbar="False" title="EkgController" windowstartuplocation="Manual" windowstyle="None" x:class="OtherThreadWindow.EkgWindow.EkgController" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:basewindow="clr-namespace:OtherThreadWindow.BaseWindow" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:gif="http://wpfanimatedgif.codeplex.com" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<grid width="140">

</grid>
</basewindow:otherthreadwindowbase>

EkgWindow.xaml.cs
public partial classEkgController :OtherThreadWindowBase
    {
        publicEkgController() : base()
        {
             InitializeComponent();
        }
    }

Step: 5

After adding GIF, create a class to add their start time, height, width, etc. using the below code.

EkgManager.cs
using System;
usingSystem.Collections.Generic;
usingSystem.Threading;
usingSystem.Windows.Threading;

namespaceOtherThreadWindow.EkgWindow
{
internalclassEkgManager
    {
privatebool _isStarting;

internalEkgManager(Dictionary settings, boolisStarting)
        {
            _isStarting = isStarting;
 
            MakeEkgOnDifferentThread();
        }

        internalvoidMakeEkgOnDifferentThread()
        {
            try
            {
                Thread newWindowThread = newThread(newThreadStart(ThreadStartingPoint));
                newWindowThread.SetApartmentState(ApartmentState.STA);
                newWindowThread.IsBackground = true;
                newWindowThread.Start();
            }
            catch (Exception ex)
            {
            }
        }

        privatevoidThreadStartingPoint()
        {
            try
            {
            if (_isStarting)
                {
                    Thread.Sleep(1900);

                    MainWindow.Current.Dispatcher.Invoke(() =>
                    {
                         MainWindow.Current.Topmost = true;
                         MainWindow.Current.Topmost = false;
                         MainWindow.Current.Activate();
                    });

                    _isStarting = false;
                }
              System.Windows.Threading.Dispatcher.Run();
            }
            catch (Exception ex)
            {
            }
        }
        internalvoidWindowSettingsChanged()
        { 
        }
        internalvoidKillEkg()
        {
        }
        internalvoidWindowActivated()
        {
        if (_isStarting) return;
        }
    }
}

Step: 6

Now, open MainWindow.XAML and create a design for the main page.

MainWindow.XAML

<basewindow:customwindow activated="MainRootActivated" background="Transparent" loaded="MainWindoLoaded" minheight="720" minwidth="1280" statechanged="MainRootStateChanged" style="{StaticResourceWindowStyle}" title="DEMO APP" x:class="OtherThreadWindow.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:basewindow="clr-namespace:OtherThreadWindow.BaseWindow" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

<windowchrome.windowchrome>
<windowchrome captionheight="0" resizeborderthickness="5" />
</windowchrome.windowchrome>

<grid background="Transparent">
<grid.columndefinitions>
<columndefinition width="*" />
<columndefinition width="Auto" />
<columndefinition width="*" />
<columndefinition width="Auto" />
<columndefinition width="50" />
</grid.columndefinitions>
<grid.rowdefinitions>
<rowdefinition height="Auto" />
<rowdefinition height="*" />
</grid.rowdefinitions>

<grid background="#000000" />
<grid background="#000000" />

<grid grid.column="3" height="86.9" width="100" />

<grid background="White"><button click="MakeYourMainWindowBusy" content="Make MainWindow Busy for 5 sec." height="40" horizontalalignment="Center" verticalalignment="Center"></button><button click="Button_Click" content="Open Custom Dialog Window" height="40" horizontalalignment="Center" margin="0,100,0,0" verticalalignment="Center"></button><button click="MakeYourMainWindowBusy" content="Make MainWindow Busy for 5 sec." height="40" horizontalalignment="Center" verticalalignment="Center"></button></grid>
</grid>

</basewindow:customwindow>

Step: 7

Open MainWindow.XAML.cs file and add the below code.

MainWindow.xaml.cs
usingOtherThreadWindow.BaseWindow;
usingOtherThreadWindow.EkgWindow;
using System;
usingSystem.Collections.Generic;
usingSystem.Threading;
usingSystem.Threading.Tasks;
usingSystem.Windows;
usingSystem.Windows.Forms;

namespaceOtherThreadWindow
{
publicpartialclassMainWindow :CustomWindow
    {
        publicMainWindow()
        {
            Current = this;

            InitializeComponent();

             LocationChanged += WindowLocationChangedHandler;
        }

        privatevoidWindowLocationChangedHandler(object sender, EventArgs e)
        {
            GetEkgSettings();
        }

        publicstaticMainWindow Current { get; set; }

        privatevoidButton_Click(object sender, RoutedEventArgs e)
        {
            vardialogWindow = newDialogWindow();
            dialogWindow.Width = 900;
            dialogWindow.Height = 600;
            dialogWindow.Owner = this;
            dialogWindow.Title = "Custom Dialog Window Title";

        dialogWindow.ShowDialog();
            { 
            }
        }
        privatevoidGetEkgSettings()
        {
        }

        internalstaticdoubleGetWindowsScalingWidth()
        {
            returnScreen.PrimaryScreen.Bounds.Width / SystemParameters.PrimaryScreenWidth;
        }

        internalstaticdoubleGetWindowsScalingHeight()
        {
            returnScreen.PrimaryScreen.Bounds.Height / SystemParameters.PrimaryScreenHeight;
        }

        privatevoidMainWindoLoaded(object sender, RoutedEventArgs e)
        {
        }

        privatevoidMainRootActivated(object sender, EventArgs e)
        {
        }

        privatevoidMainRootStateChanged(object sender, EventArgs e)
        {
        }
        privatevoidMakeYourMainWindowBusy(object sender, RoutedEventArgs e)
        {
            Thread.Sleep(5000);
        }

        ~MainWindow()
        {
            LocationChanged -= WindowLocationChangedHandler;
        }
    }
}

Step: 8

Now, we can create one more content page for when we click the main window that will be open the second window.

DialogWindow.XAML

<basewindow:customdialogwindow mc:ignorable="d" style="{StaticResourceDialogWindowStyle}" title="DialogWindow" x:class="OtherThreadWindow.DialogWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:basewindow="clr-namespace:OtherThreadWindow.BaseWindow" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<grid margin="20">
<textblock text="It's Multi threading example." />
</grid>
</basewindow:customdialogwindow>

Step: 9

Open DialogWindow.xaml.cs and inherit CustomDialogWindow.cs file.

DialogWindow.xaml.cs
usingOtherThreadWindow.BaseWindow;

namespaceOtherThreadWindow
{
    publicpartialclassDialogWindow :CustomDialogWindow
    {
        publicDialogWindow()
        {
             InitializeComponent();
        }
    }
}

Output:

Fig: Multithreading example

Fig: Window busy for 5 second

Fig: Open another window

Conclusion

In this blog, we have acquired a basic understanding of threads, their advantages and disadvantages, and their process. Using thread, we can maintain a responsive user interface.

Concept of Multithreading in Windows

Multithreading-Windows

What is Thread?

A thread is a separate execution path within a program and Window is a multithreading operating system that manages threads. In WPF when we execute a program each program is assigned a single thread by default.

There are many benefits to use multithreading in Windows applications. Let’s see the benefits of Multithreading in Windows applications.

  1. Improve performance and concurrency
  2. Simplified coding of remote procedure calls and conversation
  3. Simultaneous access to multiple applications
  4. Reduce the number of required servers

There are also some disadvantages to use multithreading in the Window application.

  1. Writing a line of code is difficult
  2. Debugging the program is difficult
  3. Managing concurrency is difficult

Now, let’s start the coding part.

Step: 1

Create a Window application. And here we need to create classes for creating windows. So first create one folder and inside the folder add a class file and add the below code.

CustomDialogWindow.cs
usingSystem.ComponentModel;
usingSystem.Windows;
usingSystem.Windows.Input;

namespaceOtherThreadWindow.BaseWindow
{
    publicclassCustomDialogWindow : Window, INotifyPropertyChanged
    {
     publiceventPropertyChangedEventHandlerPropertyChanged;

        publicCustomDialogWindow()
        {
           this.CommandBindings.Add(newCommandBinding(SystemCommands.CloseWindowCommand, OnCloseWindow));

           DataContext = this;
        }

        publicvoidOnPropertyChanged(stringpropertyName)
        {
           PropertyChanged?.Invoke(this, newPropertyChangedEventArgs(propertyName));
        }

         publicvirtualvoidOnDragWindow(object sender, MouseButtonEventArgs e)
        {
           if (e.LeftButton != MouseButtonState.Pressed)
           return;

           else
            {
                DragMove();
            }
        }

        publicvoidOnCloseWindow(object sender, ExecutedRoutedEventArgs e)
        {
                this.Close();
        }
    }
}

This class is used for a second dialog window.



Step: 2

Now, we can add a class for a custom window.

CustomWindow.cs
using System;
usingSystem.Windows;
usingSystem.Windows.Input;
using Cursors = System.Windows.Input.Cursors;
usingMouseEventArgs = System.Windows.Input.MouseEventArgs;

namespaceOtherThreadWindow.BaseWindow
{
    publicclassCustomWindow :CustomDialogWindow
    {
       private Visibility _normalizeWindowBtnVisibility;
       private Visibility _maximizeWindowBtnVisibility;

       public Visibility MaximizeWindowBtnVisibility
       {
          get{ return _maximizeWindowBtnVisibility; }
          set
            {
            if (_maximizeWindowBtnVisibility != value)
                {
                    _maximizeWindowBtnVisibility = value;
                    OnPropertyChanged(nameof(MaximizeWindowBtnVisibility));
                }
            }
        }
       public Visibility NormalizeWindowBtnVisibility
        {
          get{ return _normalizeWindowBtnVisibility; }
          set
            {
               if (_normalizeWindowBtnVisibility != value)
                {
                    _normalizeWindowBtnVisibility = value;
                    OnPropertyChanged(nameof(NormalizeWindowBtnVisibility));
                }
            }
        }
        publicCustomWindow()
        {
             this.SourceInitialized += Window_OnSourceInitialized;
             this.PreviewMouseMove += Window_OnPreviewMouseMove;
        }

        publicvoidWindow_OnSourceInitialized(object sender, EventArgs e)
        {
           if (this.WindowState == WindowState.Maximized)
            {
               MaximizeWindowBtnVisibility = Visibility.Collapsed;
               NormalizeWindowBtnVisibility = Visibility.Visible;
            }
            elseif (this.WindowState == WindowState.Normal)
            {
               MaximizeWindowBtnVisibility = Visibility.Visible;
               NormalizeWindowBtnVisibility = Visibility.Collapsed;
            }
        }

        publicvoidWindow_OnPreviewMouseMove(object sender, MouseEventArgs e)
        {
           if (e.LeftButton != MouseButtonState.Pressed)
                Cursor = Cursors.Arrow;
        }

        publicoverridevoidOnDragWindow(object sender, MouseButtonEventArgs e)
        {
              if (e.ClickCount == 2)
              return;

              if (e.LeftButton != MouseButtonState.Pressed)
              return;

            {
              DragMove();
            }
        }

        publicvoidButtonMinimize_OnClick(object sender, RoutedEventArgs e)
        {
           WindowState = WindowState.Minimized;
        }

        publicvoidButtonMaximize_OnClick(object sender, RoutedEventArgs e)
        {
           WindowState = WindowState.Maximized;
           ShowRestoreDownButton();
        }

        publicvoidShowRestoreDownButton()
        {
           MaximizeWindowBtnVisibility = Visibility.Collapsed;
           NormalizeWindowBtnVisibility = Visibility.Visible;
        }

        publicvoidShowMaximumWindowButton()
        {
           NormalizeWindowBtnVisibility = Visibility.Collapsed;
           MaximizeWindowBtnVisibility = Visibility.Visible;
        }

        publicvoidButtonRestoreDown_OnClick(object sender, RoutedEventArgs e)
        {
           ShowMaximumWindowButton();
        }

        privatevoidSwitchState()
        {
        switch (WindowState)
            {
               caseWindowState.Normal:
                    {
                        WindowState = WindowState.Maximized;
                        ShowRestoreDownButton();
                        break;
                    }
              caseWindowState.Maximized:
                    {
                        ShowMaximumWindowButton();
                        break;
                    }
            }
        }

        publicvoidButton_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
             if ((ResizeMode == ResizeMode.CanResize) ||
             (ResizeMode == ResizeMode.CanResizeWithGrip))
             {
                   SwitchState();
                   return;
            }
        }

        ~CustomWindow()
        {
              this.SourceInitialized -= Window_OnSourceInitialized;
              this.PreviewMouseMove -= Window_OnPreviewMouseMove;
        }
    }
}

Step: 3

OtherthreadwindowBase.cs
using System;
usingSystem.Runtime.InteropServices;
usingSystem.Windows;
usingSystem.Windows.Interop;

namespaceOtherThreadWindow.BaseWindow
{
    publicclassOtherThreadWindowBase : Window, IDisposable
    {
        publicvoidDispose()
        {
        try
            {
                GC.Collect();
                GC.WaitForPendingFinalizers();
            }
        catch (Exception ex)
            {

            }
        }
    }
}

One Stop Solution for WPF Application Development ?

Your Search ends here.


Step: 4

Now, we can write a code for animation. For this, you need to add one content page. On the page add the below code. And add one GIF in the resources folder.

EkgWindow.xaml

Here, we can add GIF for animation. And inherit base class on code-behind.
 


<basewindow:otherthreadwindowbase allowstransparency="True" background="#000000" mc:ignorable="d" showintaskbar="False" title="EkgController" windowstartuplocation="Manual" windowstyle="None" x:class="OtherThreadWindow.EkgWindow.EkgController" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:basewindow="clr-namespace:OtherThreadWindow.BaseWindow" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:gif="http://wpfanimatedgif.codeplex.com" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<grid width="140">

</grid>
</basewindow:otherthreadwindowbase>

EkgWindow.xaml.cs
public partial classEkgController :OtherThreadWindowBase
    {
        publicEkgController() : base()
        {
             InitializeComponent();
        }
    }

Step: 5

After adding GIF, create a class to add their start time, height, width, etc. using the below code.

EkgManager.cs
using System;
usingSystem.Collections.Generic;
usingSystem.Threading;
usingSystem.Windows.Threading;

namespaceOtherThreadWindow.EkgWindow
{
internalclassEkgManager
    {
privatebool _isStarting;

internalEkgManager(Dictionary settings, boolisStarting)
        {
            _isStarting = isStarting;
 
            MakeEkgOnDifferentThread();
        }

        internalvoidMakeEkgOnDifferentThread()
        {
            try
            {
                Thread newWindowThread = newThread(newThreadStart(ThreadStartingPoint));
                newWindowThread.SetApartmentState(ApartmentState.STA);
                newWindowThread.IsBackground = true;
                newWindowThread.Start();
            }
            catch (Exception ex)
            {
            }
        }

        privatevoidThreadStartingPoint()
        {
            try
            {
            if (_isStarting)
                {
                    Thread.Sleep(1900);

                    MainWindow.Current.Dispatcher.Invoke(() =>
                    {
                         MainWindow.Current.Topmost = true;
                         MainWindow.Current.Topmost = false;
                         MainWindow.Current.Activate();
                    });

                    _isStarting = false;
                }
              System.Windows.Threading.Dispatcher.Run();
            }
            catch (Exception ex)
            {
            }
        }
        internalvoidWindowSettingsChanged()
        { 
        }
        internalvoidKillEkg()
        {
        }
        internalvoidWindowActivated()
        {
        if (_isStarting) return;
        }
    }
}

Step: 6

Now, open MainWindow.XAML and create a design for the main page.

MainWindow.XAML

<basewindow:customwindow activated="MainRootActivated" background="Transparent" loaded="MainWindoLoaded" minheight="720" minwidth="1280" statechanged="MainRootStateChanged" style="{StaticResourceWindowStyle}" title="DEMO APP" x:class="OtherThreadWindow.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:basewindow="clr-namespace:OtherThreadWindow.BaseWindow" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

<windowchrome.windowchrome>
<windowchrome captionheight="0" resizeborderthickness="5" />
</windowchrome.windowchrome>

<grid background="Transparent">
<grid.columndefinitions>
<columndefinition width="*" />
<columndefinition width="Auto" />
<columndefinition width="*" />
<columndefinition width="Auto" />
<columndefinition width="50" />
</grid.columndefinitions>
<grid.rowdefinitions>
<rowdefinition height="Auto" />
<rowdefinition height="*" />
</grid.rowdefinitions>

<grid background="#000000" />
<grid background="#000000" />

<grid grid.column="3" height="86.9" width="100" />

<grid background="White"><button click="MakeYourMainWindowBusy" content="Make MainWindow Busy for 5 sec." height="40" horizontalalignment="Center" verticalalignment="Center"></button><button click="Button_Click" content="Open Custom Dialog Window" height="40" horizontalalignment="Center" margin="0,100,0,0" verticalalignment="Center"></button><button click="MakeYourMainWindowBusy" content="Make MainWindow Busy for 5 sec." height="40" horizontalalignment="Center" verticalalignment="Center"></button></grid>
</grid>

</basewindow:customwindow>

Step: 7

Open MainWindow.XAML.cs file and add the below code.

MainWindow.xaml.cs
usingOtherThreadWindow.BaseWindow;
usingOtherThreadWindow.EkgWindow;
using System;
usingSystem.Collections.Generic;
usingSystem.Threading;
usingSystem.Threading.Tasks;
usingSystem.Windows;
usingSystem.Windows.Forms;

namespaceOtherThreadWindow
{
publicpartialclassMainWindow :CustomWindow
    {
        publicMainWindow()
        {
            Current = this;

            InitializeComponent();

             LocationChanged += WindowLocationChangedHandler;
        }

        privatevoidWindowLocationChangedHandler(object sender, EventArgs e)
        {
            GetEkgSettings();
        }

        publicstaticMainWindow Current { get; set; }

        privatevoidButton_Click(object sender, RoutedEventArgs e)
        {
            vardialogWindow = newDialogWindow();
            dialogWindow.Width = 900;
            dialogWindow.Height = 600;
            dialogWindow.Owner = this;
            dialogWindow.Title = "Custom Dialog Window Title";

        dialogWindow.ShowDialog();
            { 
            }
        }
        privatevoidGetEkgSettings()
        {
        }

        internalstaticdoubleGetWindowsScalingWidth()
        {
            returnScreen.PrimaryScreen.Bounds.Width / SystemParameters.PrimaryScreenWidth;
        }

        internalstaticdoubleGetWindowsScalingHeight()
        {
            returnScreen.PrimaryScreen.Bounds.Height / SystemParameters.PrimaryScreenHeight;
        }

        privatevoidMainWindoLoaded(object sender, RoutedEventArgs e)
        {
        }

        privatevoidMainRootActivated(object sender, EventArgs e)
        {
        }

        privatevoidMainRootStateChanged(object sender, EventArgs e)
        {
        }
        privatevoidMakeYourMainWindowBusy(object sender, RoutedEventArgs e)
        {
            Thread.Sleep(5000);
        }

        ~MainWindow()
        {
            LocationChanged -= WindowLocationChangedHandler;
        }
    }
}

Step: 8

Now, we can create one more content page for when we click the main window that will be open the second window.

DialogWindow.XAML

<basewindow:customdialogwindow mc:ignorable="d" style="{StaticResourceDialogWindowStyle}" title="DialogWindow" x:class="OtherThreadWindow.DialogWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:basewindow="clr-namespace:OtherThreadWindow.BaseWindow" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<grid margin="20">
<textblock text="It's Multi threading example." />
</grid>
</basewindow:customdialogwindow>

Step: 9

Open DialogWindow.xaml.cs and inherit CustomDialogWindow.cs file.

DialogWindow.xaml.cs
usingOtherThreadWindow.BaseWindow;

namespaceOtherThreadWindow
{
    publicpartialclassDialogWindow :CustomDialogWindow
    {
        publicDialogWindow()
        {
             InitializeComponent();
        }
    }
}

Output:

Fig: Multithreading example

Fig: Window busy for 5 second

Fig: Open another window

Conclusion

In this blog, we have acquired a basic understanding of threads, their advantages and disadvantages, and their process. Using thread, we can maintain a responsive user interface.