Results 1 to 7 of 7

Thread: [RESOLVED] BackgroundWorker is not able to prevent ProgressBar freezing

  1. #1

    Thread Starter
    Addicted Member Kram Kramer's Avatar
    Join Date
    Dec 2016
    Posts
    131

    Resolved [RESOLVED] BackgroundWorker is not able to prevent ProgressBar freezing

    1- Copy and paste the following codes into MainWindow.xaml file.

    Code:
    <Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
    <Grid>
        <DataGrid x:Name="DataGrid1"/>
    </Grid>
    </Window>
    2- Copy and paste the following codes into MainWindow.xaml.cs file.

    Code:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    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.ComponentModel;
    using System.Threading;
    
    namespace WpfApplication1
    {
    
    public partial class MainWindow : Window
    {
        BackgroundWorker BackgroundWorker1 = new BackgroundWorker();
        BackgroundWorker BackgroundWorker2 = new BackgroundWorker();
        System.Data.DataTable DataTable1 = new System.Data.DataTable();
    
        public MainWindow()
        {
            InitializeComponent();
            BackgroundWorker1.DoWork += BackgroundWorker1_DoWork;
            BackgroundWorker2.DoWork += BackgroundWorker2_DoWork;
        }
    
        void Window_Loaded(object sender, RoutedEventArgs e)
        {
            BackgroundWorker1.RunWorkerAsync();
            BackgroundWorker2.RunWorkerAsync();
        }
    
        private void BackgroundWorker1_DoWork(System.Object sender, System.ComponentModel.DoWorkEventArgs e)
        {
            Dispatcher.Invoke(() =>
            {
                Window1 myWindow1 = new Window1();
                myWindow1.ShowDialog();
            });
        }
    
        private void BackgroundWorker2_DoWork(System.Object sender, System.ComponentModel.DoWorkEventArgs e)
        {
            for (int i = 1; i <= 7; i++)
                DataTable1.Columns.Add();
            for (int i = 1; i <= 1048576; i++)
                DataTable1.Rows.Add(i);
            Dispatcher.Invoke(() =>
            {
                DataGrid1.ItemsSource = DataTable1.DefaultView;
            });
        }
    
    }
    }
    3- Create a new Window and named it as Window1.

    4- Copy and paste the following codes into Window1.xaml file.

    Code:
    <Window x:Class="WpfApplication1.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="300" Width="1000" ContentRendered="Window_ContentRendered">
    <Grid>
        <ProgressBar x:Name="ProgressBar1" Height="25" Width="850"/>
    </Grid>
    </Window>
    5- Copy and paste the following codes into Window1.xaml.cs file.

    Code:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    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;
    
    namespace WpfApplication1
    {
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }
    
        private void Window_ContentRendered(object sender, EventArgs e)
        {
            ProgressBar1.IsIndeterminate = true;
        }
    }
    }
    6- When you run this project you will see that ProgressBar1 is freezing for two or three seconds while the following line runs because of adding 1048576 rows to the DataGrid. (Huge rows)

    Code:
    DataGrid1.ItemsSource = DataTable1.DefaultView;
    I dont want ProgressBar1 is freezing.

    So why BackgroundWorker is not able to prevent ProgressBar freezing?
    Last edited by Kram Kramer; Nov 14th, 2019 at 05:59 AM.

  2. #2
    Smooth Moperator techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,531

    Re: BackgroundWorker is not able to prevent ProgressBar freezing

    Because UI work still happens on the main UI thread. When you call that line, it's being done through an invoke which means it's going back to the main UI thread to be executed (as it should be). Threads are single minded and can only do one thing at a time... so it's either keep the prog bar going, or it's update the grid with the data it just got. New data trumps the old, so it pauses the progbar for a moment, updates your grid, then resumes your progbar.

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  3. #3
    Sinecure devotee
    Join Date
    Aug 2013
    Location
    Southern Tier NY
    Posts
    6,582

    Re: BackgroundWorker is not able to prevent ProgressBar freezing

    You could use a background thread with the ApartmentState set to SingleThreadedApartment (STA) to show your window.
    Code:
        public partial class MainWindow : Window
        {
     //       BackgroundWorker BackgroundWorker1 = new BackgroundWorker();
            Thread ProgressThread;
            BackgroundWorker BackgroundWorker2 = new BackgroundWorker();
    
            System.Data.DataTable DataTable1 = new System.Data.DataTable();
    
            public MainWindow()
            {
                InitializeComponent();
     //           BackgroundWorker1.DoWork += BackgroundWorker1_DoWork;
                BackgroundWorker2.DoWork += BackgroundWorker2_DoWork;
            }
    
            void Window_Loaded(object sender, RoutedEventArgs e)
            {
                // BackgroundWorker1.RunWorkerAsync();
                ProgressThread = new Thread(testThread);
                ProgressThread.SetApartmentState(ApartmentState.STA);
                ProgressThread.IsBackground = true;
                ProgressThread.Start();
    
                BackgroundWorker2.RunWorkerAsync();
            }
    
            private void testThread()
            {
                Window1 myWindow1 = new Window1();
                myWindow1.ShowDialog();
            }
    "Anyone can do any amount of work, provided it isn't the work he is supposed to be doing at that moment" Robert Benchley, 1930

  4. #4

    Thread Starter
    Addicted Member Kram Kramer's Avatar
    Join Date
    Dec 2016
    Posts
    131

    Re: BackgroundWorker is not able to prevent ProgressBar freezing

    Hi passel,
    Thank you very much.
    Your solution looks okey.

    I want to know your comments regarding the other answers here:
    https://stackoverflow.com/questions/...populating-dyn

    For example they are recommended using ObservableCollection instead of DataTable. What do you think using ObservableCollection instead of DataTable?
    Last edited by Kram Kramer; Nov 14th, 2019 at 09:16 AM.

  5. #5
    Sinecure devotee
    Join Date
    Aug 2013
    Location
    Southern Tier NY
    Posts
    6,582

    Re: BackgroundWorker is not able to prevent ProgressBar freezing

    I know almost nothing about data related issues, i.e. no database experience, and very little experience with using a DataTable and none using an ObservableCollection.
    I don't even normally use C#, but since this was a .Net threading/GUI issue and directly relatable to VB.Net, I decided to try your code, and see if I could figure out how to create the form in the background thread so that the background thread was in control of that GUI, as could be done in VB.Net. It was simple enough, so there you go.

    Probably any other questions you have will be out of my area of experience.
    "Anyone can do any amount of work, provided it isn't the work he is supposed to be doing at that moment" Robert Benchley, 1930

  6. #6
    Smooth Moperator techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,531

    Re: BackgroundWorker is not able to prevent ProgressBar freezing

    Quote Originally Posted by Kram Kramer View Post
    Hi passel,
    Thank you very much.
    Your solution looks okey.

    I want to know your comments regarding the other answers here:
    https://stackoverflow.com/questions/...populating-dyn

    For example they are recommended using ObservableCollection instead of DataTable. What do you think using ObservableCollection instead of DataTable?
    Hmmm.... this is stretching my grey matter a bit as it goes back into the memory banks some, so I may not have this quite right, but here goes...
    Both a Datatable and ObservableCollection can be bound to UI elements, say a grid, or something...and it will display... the differences are two fold. 1) An ObservableCollection can hold objects... while a datatable can only hold datarows. So if you have a custom class of somehting, and OC may work better than an DT, because otherwise you'd have to convert it from your class to a DR. 2) OCs allow for state changes and updates. If you update a value within your collection, the change will bubble up and allow the change to be Observable (thus the name) and allow the change to be reflected in the display if it is bound to somehting in the UI - with out you having to do anything further. In short, the OC takes care of the plumbing to allow changes to be observed and displayed in the UI.

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  7. #7

    Thread Starter
    Addicted Member Kram Kramer's Avatar
    Join Date
    Dec 2016
    Posts
    131

    Re: BackgroundWorker is not able to prevent ProgressBar freezing

    Thank you very much. Solved.
    Last edited by Kram Kramer; Nov 14th, 2019 at 04:10 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width