Wednesday, January 7, 2015

Hoe to use BackgroundWorker in WPF

Sample window:

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="BackgroundWorkerTest" Height="300" Width="300">
   
       
       
       
       
       
   


Code behind :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.ComponentModel;
using WpfFinalApp.TestService;
using System.Threading;
namespace WpfFinalApp
{
    ///
    /// Interaction logic for BackgroundWorkerTest.xaml
    ///
    public partial class BackgroundWorkerTest : Window
    {
        //TestService.Service1Client service = new TestService.Service1Client();
        BackgroundWorker bg = new BackgroundWorker();
   
        public BackgroundWorkerTest()
        {
            InitializeComponent();

            //To Support cancellation
            bg.WorkerSupportsCancellation = true;
            //To Show Progress
            bg.WorkerReportsProgress = true;

            //Event Handlers
            bg.DoWork += new DoWorkEventHandler(bg_DoWork);
            bg.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bg_RunWorkerCompleted);
            bg.ProgressChanged += new ProgressChangedEventHandler(bg_ProgressChanged);
        }

        void bg_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            label2.Content = e.ProgressPercentage.ToString();
        }

        void bg_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if(e.Cancelled==false)
            textBox1.Text = e.Result.ToString();
            //MessageBox.Show("bg_RunWorkerCompleted result");
        }

        void bg_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;
           int i=0;
           for (i=0; i < 100; i++)
           {

               if (worker.CancellationPending)
               {
                   e.Cancel = true;
                   break;
               }
               bg.ReportProgress(i+1);
               Thread.Sleep(100);
           }
           e.Result = i;
           //textBox1.Dispatcher.BeginInvoke((Delegate)()=>{textBox1.Text=i.ToString();},null);
            //MessageBox.Show("bg_DoWork result");
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            if(!bg.IsBusy)
            bg.RunWorkerAsync();
         
        }

        private void button2_Click(object sender, RoutedEventArgs e)
        {
            if (!bg.CancellationPending)
                bg.CancelAsync();
        }
    }
}

Note : Please correct namespace and window name

How to Update WPF control from different Thread

Suppose I have a window with 2 label and I will show number's on label from a new thread:

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
   
       
       
   


Code Behind:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Threading;

namespace ThreadingTest
{
    ///
    /// Interaction logic for MainWindow.xaml
    ///
    public partial class MainWindow : Window
    {
        public delegate void MyDelegate();
        int n;
        int k = 0;
        public MainWindow()
        {
            InitializeComponent();

            Thread t = new Thread(ThreadMethod);
            n = 20;
            t.Start();
           
        }
        public  void ThreadMethod()
        {
            for (int i = 0; i < n; i++)
            {
                Thread.Sleep(1000);
                label1.Dispatcher.BeginInvoke(new MyDelegate(()=>
                {
                    label1.Content = i.ToString();
                }
                 ));
             
            }
        }
    }
}


Note : Here important thing is that we are able to access variable from main thread to child thread but to access control we need to call Dispatcher associated with lable and then need to call BeginInvoke() or Invoke() method of it.

C# Record type: Something to remember while using record types

  Record in c# provide a concise and expressive way to create immutable data types, record is a keyword in c#, we can use this keyword with ...