Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. C# Multithreading, GUI hangs while loading

C# Multithreading, GUI hangs while loading

Scheduled Pinned Locked Moved C#
csharpdatabasedata-structuresquestion
18 Posts 4 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    Justincc
    wrote on last edited by
    #1

    My Code below is using a backgroundWorker component. My entire GUI freezes while it loads the content tree from the database. The window even says (not responding) at the top. My desired result is to have a loading animation play while loading the data from the database... am I going at this wrong? Shouldn't the loading take place in the background, preventing the GUI from freezing up? Any ideas? ___________________________________________________________ private void bgWorker_DoWork(object sender, DoWorkEventArgs e) { LoadCompanies(); } private void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { ShowLoadingAnimation(false); } private void LoadCompanies(object sender, EventArgs e) { ShowLoadingAnimation(true); this.bgWorker.RunWorkerAsync(); } private delegate void LoadCompaniesDelegate(); public void LoadCompanies() { PROSOCO.Library.Companies.Criteria criteria = PROSOCO.Library.Companies.Criteria.GetCriteria(); BindingSource src = new BindingSource(); PROSOCO.Library.Companies.Nodes nodes = PROSOCO.Library.Companies.Nodes.GetNodes(criteria.NodeCriteria()); src.DataSource = nodes; if (pnlNavigation.InvokeRequired) { LoadCompaniesDelegate find = new LoadCompaniesDelegate(LoadCompanies); this.Invoke(find, new object[] { }); } else { pnlNavigation.ContentTree.ParentMember = "ParentId"; pnlNavigation.ContentTree.ValueMember = "Id"; pnlNavigation.ContentTree.DisplayMember = "Name"; pnlNavigation.ContentTree.PrefixMember = "CustomerNumber"; pnlNavigation.ContentTree.PostfixMember = "CityState"; pnlNavigation.ContentTree.DataSource = src; } _activeModule = "Companies"; }

    L P J 3 Replies Last reply
    0
    • J Justincc

      My Code below is using a backgroundWorker component. My entire GUI freezes while it loads the content tree from the database. The window even says (not responding) at the top. My desired result is to have a loading animation play while loading the data from the database... am I going at this wrong? Shouldn't the loading take place in the background, preventing the GUI from freezing up? Any ideas? ___________________________________________________________ private void bgWorker_DoWork(object sender, DoWorkEventArgs e) { LoadCompanies(); } private void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { ShowLoadingAnimation(false); } private void LoadCompanies(object sender, EventArgs e) { ShowLoadingAnimation(true); this.bgWorker.RunWorkerAsync(); } private delegate void LoadCompaniesDelegate(); public void LoadCompanies() { PROSOCO.Library.Companies.Criteria criteria = PROSOCO.Library.Companies.Criteria.GetCriteria(); BindingSource src = new BindingSource(); PROSOCO.Library.Companies.Nodes nodes = PROSOCO.Library.Companies.Nodes.GetNodes(criteria.NodeCriteria()); src.DataSource = nodes; if (pnlNavigation.InvokeRequired) { LoadCompaniesDelegate find = new LoadCompaniesDelegate(LoadCompanies); this.Invoke(find, new object[] { }); } else { pnlNavigation.ContentTree.ParentMember = "ParentId"; pnlNavigation.ContentTree.ValueMember = "Id"; pnlNavigation.ContentTree.DisplayMember = "Name"; pnlNavigation.ContentTree.PrefixMember = "CustomerNumber"; pnlNavigation.ContentTree.PostfixMember = "CityState"; pnlNavigation.ContentTree.DataSource = src; } _activeModule = "Companies"; }

      L Offline
      L Offline
      Luc Pattyn
      wrote on last edited by
      #2

      Hi, you seem aware of the fact that controls are not thread-safe, so you try to use InvokeRequired and Invoke(), but IMO there are some mistakes in the implementation\; the normal pattern is a method that ONLY contains something like if (InvokeRequired) Invoke(delegate) else do_whatever_needs_to_be_done_to_the_GUI Your public void LoadCompanies() method however contains stuff before the if; that stuff will execute twice, the second time on the GUI (bad for responsiveness); it also generates two BindingSource objects, only the second one will be used. I suggest you split the method in two parts, i.e. move the second half (the if-else) to a separate method, and apply the pattern to it, hence avoiding the first half to be executed twice (of which once on the GUI) :)

      Luc Pattyn


      try { [Search CP Articles] [Search CP Forums] [Forum Guidelines] [My Articles] } catch { [Google] }


      J 1 Reply Last reply
      0
      • L Luc Pattyn

        Hi, you seem aware of the fact that controls are not thread-safe, so you try to use InvokeRequired and Invoke(), but IMO there are some mistakes in the implementation\; the normal pattern is a method that ONLY contains something like if (InvokeRequired) Invoke(delegate) else do_whatever_needs_to_be_done_to_the_GUI Your public void LoadCompanies() method however contains stuff before the if; that stuff will execute twice, the second time on the GUI (bad for responsiveness); it also generates two BindingSource objects, only the second one will be used. I suggest you split the method in two parts, i.e. move the second half (the if-else) to a separate method, and apply the pattern to it, hence avoiding the first half to be executed twice (of which once on the GUI) :)

        Luc Pattyn


        try { [Search CP Articles] [Search CP Forums] [Forum Guidelines] [My Articles] } catch { [Google] }


        J Offline
        J Offline
        Justincc
        wrote on last edited by
        #3

        It still has the same isse. I'm not sure I understood your suggestion, but I updated it as shown below. However, the gui still hangs while loading the companies. public void LoadCompanies() { if (pnlNavigation.InvokeRequired) { LoadCompaniesDelegate find = new LoadCompaniesDelegate(LoadCompanies); this.Invoke(find, new object[] { }); } else { PROSOCO.Library.Companies.Criteria criteria = PROSOCO.Library.Companies.Criteria.GetCriteria(); BindingSource src = new BindingSource(); PROSOCO.Library.Companies.Nodes nodes = PROSOCO.Library.Companies.Nodes.GetNodes(criteria.NodeCriteria()); src.DataSource = nodes; pnlNavigation.ContentTree.ParentMember = "ParentId"; pnlNavigation.ContentTree.ValueMember = "Id"; pnlNavigation.ContentTree.DisplayMember = "Name"; pnlNavigation.ContentTree.PrefixMember = "CustomerNumber"; pnlNavigation.ContentTree.PostfixMember = "CityState"; pnlNavigation.ContentTree.DataSource = src; } _activeModule = "Companies"; }

        P L 2 Replies Last reply
        0
        • J Justincc

          My Code below is using a backgroundWorker component. My entire GUI freezes while it loads the content tree from the database. The window even says (not responding) at the top. My desired result is to have a loading animation play while loading the data from the database... am I going at this wrong? Shouldn't the loading take place in the background, preventing the GUI from freezing up? Any ideas? ___________________________________________________________ private void bgWorker_DoWork(object sender, DoWorkEventArgs e) { LoadCompanies(); } private void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { ShowLoadingAnimation(false); } private void LoadCompanies(object sender, EventArgs e) { ShowLoadingAnimation(true); this.bgWorker.RunWorkerAsync(); } private delegate void LoadCompaniesDelegate(); public void LoadCompanies() { PROSOCO.Library.Companies.Criteria criteria = PROSOCO.Library.Companies.Criteria.GetCriteria(); BindingSource src = new BindingSource(); PROSOCO.Library.Companies.Nodes nodes = PROSOCO.Library.Companies.Nodes.GetNodes(criteria.NodeCriteria()); src.DataSource = nodes; if (pnlNavigation.InvokeRequired) { LoadCompaniesDelegate find = new LoadCompaniesDelegate(LoadCompanies); this.Invoke(find, new object[] { }); } else { pnlNavigation.ContentTree.ParentMember = "ParentId"; pnlNavigation.ContentTree.ValueMember = "Id"; pnlNavigation.ContentTree.DisplayMember = "Name"; pnlNavigation.ContentTree.PrefixMember = "CustomerNumber"; pnlNavigation.ContentTree.PostfixMember = "CityState"; pnlNavigation.ContentTree.DataSource = src; } _activeModule = "Companies"; }

          P Offline
          P Offline
          PhilDanger
          wrote on last edited by
          #4

          I'm not quite sure what the LoadCompanies is supposed to be doing, but focus on this part:

            if (pnlNavigation.InvokeRequired) //checks to see if the current function is on the same thread as the object
            {
                  LoadCompaniesDelegate find = new LoadCompaniesDelegate(LoadCompanies); //sets up a recursive call to LoadCompanies?
                  this.Invoke(find, new object\[\] { }); //runs the LoadCompanies on the panel's thread
            }
            else
            {
                  pnlNavigation.ContentTree.ParentMember = "ParentId";
                  pnlNavigation.ContentTree.ValueMember = "Id";
                  pnlNavigation.ContentTree.DisplayMember = "Name";
                  pnlNavigation.ContentTree.PrefixMember = "CustomerNumber";
                  pnlNavigation.ContentTree.PostfixMember = "CityState";
                  pnlNavigation.ContentTree.DataSource = src;
            }
          

          As you can see by the comments, the BackgroundWorker will indeed run LoadCompanies on its own thread. You then check for InvokeRequired -- since crossthreaded operations are illegal, this function returns true if the object is on another thread. If it is (which I'm guessing pnlNavigation is a GUI element on the GUI thread), you then call Invoke to call LoadCompanies, which forces it to run on the GUI thread! So you're back where you started, and you have to load from the database AGAIN!

          J 1 Reply Last reply
          0
          • P PhilDanger

            I'm not quite sure what the LoadCompanies is supposed to be doing, but focus on this part:

              if (pnlNavigation.InvokeRequired) //checks to see if the current function is on the same thread as the object
              {
                    LoadCompaniesDelegate find = new LoadCompaniesDelegate(LoadCompanies); //sets up a recursive call to LoadCompanies?
                    this.Invoke(find, new object\[\] { }); //runs the LoadCompanies on the panel's thread
              }
              else
              {
                    pnlNavigation.ContentTree.ParentMember = "ParentId";
                    pnlNavigation.ContentTree.ValueMember = "Id";
                    pnlNavigation.ContentTree.DisplayMember = "Name";
                    pnlNavigation.ContentTree.PrefixMember = "CustomerNumber";
                    pnlNavigation.ContentTree.PostfixMember = "CityState";
                    pnlNavigation.ContentTree.DataSource = src;
              }
            

            As you can see by the comments, the BackgroundWorker will indeed run LoadCompanies on its own thread. You then check for InvokeRequired -- since crossthreaded operations are illegal, this function returns true if the object is on another thread. If it is (which I'm guessing pnlNavigation is a GUI element on the GUI thread), you then call Invoke to call LoadCompanies, which forces it to run on the GUI thread! So you're back where you started, and you have to load from the database AGAIN!

            J Offline
            J Offline
            Justincc
            wrote on last edited by
            #5

            I changed LoadCompanies so as best I can tell, it isn't loading anything twice. It still has the same (not responding) issue while it loads all the records into the ContentTree. public void LoadCompanies() { if (pnlNavigation.InvokeRequired) { LoadCompaniesDelegate find = new LoadCompaniesDelegate(LoadCompanies); this.Invoke(find, new object[] { }); } else { PROSOCO.Library.Companies.Criteria criteria = PROSOCO.Library.Companies.Criteria.GetCriteria(); BindingSource src = new BindingSource(); PROSOCO.Library.Companies.Nodes nodes = PROSOCO.Library.Companies.Nodes.GetNodes(criteria.NodeCriteria()); src.DataSource = nodes; pnlNavigation.ContentTree.ParentMember = "ParentId"; pnlNavigation.ContentTree.ValueMember = "Id"; pnlNavigation.ContentTree.DisplayMember = "Name"; pnlNavigation.ContentTree.PrefixMember = "CustomerNumber"; pnlNavigation.ContentTree.PostfixMember = "CityState"; pnlNavigation.ContentTree.DataSource = src; } _activeModule = "Companies"; }

            P 1 Reply Last reply
            0
            • J Justincc

              It still has the same isse. I'm not sure I understood your suggestion, but I updated it as shown below. However, the gui still hangs while loading the companies. public void LoadCompanies() { if (pnlNavigation.InvokeRequired) { LoadCompaniesDelegate find = new LoadCompaniesDelegate(LoadCompanies); this.Invoke(find, new object[] { }); } else { PROSOCO.Library.Companies.Criteria criteria = PROSOCO.Library.Companies.Criteria.GetCriteria(); BindingSource src = new BindingSource(); PROSOCO.Library.Companies.Nodes nodes = PROSOCO.Library.Companies.Nodes.GetNodes(criteria.NodeCriteria()); src.DataSource = nodes; pnlNavigation.ContentTree.ParentMember = "ParentId"; pnlNavigation.ContentTree.ValueMember = "Id"; pnlNavigation.ContentTree.DisplayMember = "Name"; pnlNavigation.ContentTree.PrefixMember = "CustomerNumber"; pnlNavigation.ContentTree.PostfixMember = "CityState"; pnlNavigation.ContentTree.DataSource = src; } _activeModule = "Companies"; }

              P Offline
              P Offline
              PhilDanger
              wrote on last edited by
              #6

              This still makes it execute on the GUI thread. One idea would be to run everything but the actual GUI stuff in the background. When BackgroundWorker finishes, you can return the data that you need to load the GUI stuff (Binding Source) through the DoWorkEventArgs.Result (which gets sent to the RunWorkerCompletedEvent when it finish DoWork). You then cast the Result to a BindingSource and do the last portion of your code (after src.DataSource = nodes; ) in the GUI thread.

              J 1 Reply Last reply
              0
              • J Justincc

                I changed LoadCompanies so as best I can tell, it isn't loading anything twice. It still has the same (not responding) issue while it loads all the records into the ContentTree. public void LoadCompanies() { if (pnlNavigation.InvokeRequired) { LoadCompaniesDelegate find = new LoadCompaniesDelegate(LoadCompanies); this.Invoke(find, new object[] { }); } else { PROSOCO.Library.Companies.Criteria criteria = PROSOCO.Library.Companies.Criteria.GetCriteria(); BindingSource src = new BindingSource(); PROSOCO.Library.Companies.Nodes nodes = PROSOCO.Library.Companies.Nodes.GetNodes(criteria.NodeCriteria()); src.DataSource = nodes; pnlNavigation.ContentTree.ParentMember = "ParentId"; pnlNavigation.ContentTree.ValueMember = "Id"; pnlNavigation.ContentTree.DisplayMember = "Name"; pnlNavigation.ContentTree.PrefixMember = "CustomerNumber"; pnlNavigation.ContentTree.PostfixMember = "CityState"; pnlNavigation.ContentTree.DataSource = src; } _activeModule = "Companies"; }

                P Offline
                P Offline
                PhilDanger
                wrote on last edited by
                #7

                Yes, the double loading was only one problem. Invoke forces it to run on the thread of the object that you called it from.

                1 Reply Last reply
                0
                • J Justincc

                  It still has the same isse. I'm not sure I understood your suggestion, but I updated it as shown below. However, the gui still hangs while loading the companies. public void LoadCompanies() { if (pnlNavigation.InvokeRequired) { LoadCompaniesDelegate find = new LoadCompaniesDelegate(LoadCompanies); this.Invoke(find, new object[] { }); } else { PROSOCO.Library.Companies.Criteria criteria = PROSOCO.Library.Companies.Criteria.GetCriteria(); BindingSource src = new BindingSource(); PROSOCO.Library.Companies.Nodes nodes = PROSOCO.Library.Companies.Nodes.GetNodes(criteria.NodeCriteria()); src.DataSource = nodes; pnlNavigation.ContentTree.ParentMember = "ParentId"; pnlNavigation.ContentTree.ValueMember = "Id"; pnlNavigation.ContentTree.DisplayMember = "Name"; pnlNavigation.ContentTree.PrefixMember = "CustomerNumber"; pnlNavigation.ContentTree.PostfixMember = "CityState"; pnlNavigation.ContentTree.DataSource = src; } _activeModule = "Companies"; }

                  L Offline
                  L Offline
                  Luc Pattyn
                  wrote on last edited by
                  #8

                  No, that is not how I explained it; the else part executes on the GUI thread and hence must be fast. Take out everything that does not need to be there, and have it execute before you call public void LoadCompanies(). :)

                  Luc Pattyn


                  try { [Search CP Articles] [Search CP Forums] [Forum Guidelines] [My Articles] } catch { [Google] }


                  1 Reply Last reply
                  0
                  • J Justincc

                    My Code below is using a backgroundWorker component. My entire GUI freezes while it loads the content tree from the database. The window even says (not responding) at the top. My desired result is to have a loading animation play while loading the data from the database... am I going at this wrong? Shouldn't the loading take place in the background, preventing the GUI from freezing up? Any ideas? ___________________________________________________________ private void bgWorker_DoWork(object sender, DoWorkEventArgs e) { LoadCompanies(); } private void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { ShowLoadingAnimation(false); } private void LoadCompanies(object sender, EventArgs e) { ShowLoadingAnimation(true); this.bgWorker.RunWorkerAsync(); } private delegate void LoadCompaniesDelegate(); public void LoadCompanies() { PROSOCO.Library.Companies.Criteria criteria = PROSOCO.Library.Companies.Criteria.GetCriteria(); BindingSource src = new BindingSource(); PROSOCO.Library.Companies.Nodes nodes = PROSOCO.Library.Companies.Nodes.GetNodes(criteria.NodeCriteria()); src.DataSource = nodes; if (pnlNavigation.InvokeRequired) { LoadCompaniesDelegate find = new LoadCompaniesDelegate(LoadCompanies); this.Invoke(find, new object[] { }); } else { pnlNavigation.ContentTree.ParentMember = "ParentId"; pnlNavigation.ContentTree.ValueMember = "Id"; pnlNavigation.ContentTree.DisplayMember = "Name"; pnlNavigation.ContentTree.PrefixMember = "CustomerNumber"; pnlNavigation.ContentTree.PostfixMember = "CityState"; pnlNavigation.ContentTree.DataSource = src; } _activeModule = "Companies"; }

                    J Offline
                    J Offline
                    Judah Gabriel Himango
                    wrote on last edited by
                    #9

                    Try changing the LoadCompanies method to this instead:

                    public void LoadCompanies(DoWorkEventArgs e)
                    {
                    PROSOCO.Library.Companies.Criteria criteria = PROSOCO.Library.Companies.Criteria.GetCriteria();

                    BindingSource src = new BindingSource();

                    PROSOCO.Library.Companies.Nodes nodes = PROSOCO.Library.Companies.Nodes.GetNodes(criteria.NodeCriteria());

                    src.DataSource = nodes;

                    e.Result = src;
                    }

                    Then change your RunWorkerCompleted handler to look like this:

                    private void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
                    {
                    BindingSource src = (BindingSource)e.Result;
                    pnlNavigation.ContentTree.ParentMember = "ParentId";
                    pnlNavigation.ContentTree.ValueMember = "Id";
                    pnlNavigation.ContentTree.DisplayMember = "Name";
                    pnlNavigation.ContentTree.PrefixMember = "CustomerNumber";
                    pnlNavigation.ContentTree.PostfixMember = "CityState";
                    pnlNavigation.ContentTree.DataSource = src;

                    ShowLoadingAnimation(false);

                    \_activeModule = "Companies";
                    

                    }

                    Tech, life, family, faith: Give me a visit. I'm currently blogging about: Orthodox Jews are persecuting Messianic Jews in Israel (video) The apostle Paul, modernly speaking: Epistles of Paul Judah Himango

                    J 1 Reply Last reply
                    0
                    • P PhilDanger

                      This still makes it execute on the GUI thread. One idea would be to run everything but the actual GUI stuff in the background. When BackgroundWorker finishes, you can return the data that you need to load the GUI stuff (Binding Source) through the DoWorkEventArgs.Result (which gets sent to the RunWorkerCompletedEvent when it finish DoWork). You then cast the Result to a BindingSource and do the last portion of your code (after src.DataSource = nodes; ) in the GUI thread.

                      J Offline
                      J Offline
                      Justincc
                      wrote on last edited by
                      #10

                      I am new to C# so forgive me for not "just getting it" but this is what I have so far. I am doing something wrong because "BindingSource src = (BindingSource)e.Result;" Doesn't seem to be loading any data... Did I atleast get everything running in the background except the GUI stuff? Can you tell why I wouldn't be loading any data? Thanks in advance. private delegate object LoadCompaniesDelegate(); public object LoadCompanies() { BindingSource src = new BindingSource(); if (pnlNavigation.InvokeRequired) { LoadCompaniesDelegate find = new LoadCompaniesDelegate(LoadCompanies); this.Invoke(find, new object[] { }); } else { PROSOCO.Library.Companies.Criteria criteria = PROSOCO.Library.Companies.Criteria.GetCriteria(); PROSOCO.Library.Companies.Nodes nodes = PROSOCO.Library.Companies.Nodes.GetNodes(criteria.NodeCriteria()); src.DataSource = nodes; MessageBox.Show("Loaded Notes"); } return src; } private void bgWorker_DoWork(object sender, DoWorkEventArgs e) { e.Result = LoadCompanies(); } private void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { BindingSource src = (BindingSource)e.Result; pnlNavigation.ContentTree.ParentMember = "ParentId"; pnlNavigation.ContentTree.ValueMember = "Id"; pnlNavigation.ContentTree.DisplayMember = "Name"; pnlNavigation.ContentTree.PrefixMember = "CustomerNumber"; pnlNavigation.ContentTree.PostfixMember = "CityState"; pnlNavigation.ContentTree.DataSource = src; _activeModule = "Companies"; MessageBox.Show("Completed"); }

                      P 1 Reply Last reply
                      0
                      • J Judah Gabriel Himango

                        Try changing the LoadCompanies method to this instead:

                        public void LoadCompanies(DoWorkEventArgs e)
                        {
                        PROSOCO.Library.Companies.Criteria criteria = PROSOCO.Library.Companies.Criteria.GetCriteria();

                        BindingSource src = new BindingSource();

                        PROSOCO.Library.Companies.Nodes nodes = PROSOCO.Library.Companies.Nodes.GetNodes(criteria.NodeCriteria());

                        src.DataSource = nodes;

                        e.Result = src;
                        }

                        Then change your RunWorkerCompleted handler to look like this:

                        private void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
                        {
                        BindingSource src = (BindingSource)e.Result;
                        pnlNavigation.ContentTree.ParentMember = "ParentId";
                        pnlNavigation.ContentTree.ValueMember = "Id";
                        pnlNavigation.ContentTree.DisplayMember = "Name";
                        pnlNavigation.ContentTree.PrefixMember = "CustomerNumber";
                        pnlNavigation.ContentTree.PostfixMember = "CityState";
                        pnlNavigation.ContentTree.DataSource = src;

                        ShowLoadingAnimation(false);

                        \_activeModule = "Companies";
                        

                        }

                        Tech, life, family, faith: Give me a visit. I'm currently blogging about: Orthodox Jews are persecuting Messianic Jews in Israel (video) The apostle Paul, modernly speaking: Epistles of Paul Judah Himango

                        J Offline
                        J Offline
                        Justincc
                        wrote on last edited by
                        #11

                        It is still freezing the GUI. Let me know if I am doing this how you reccomended or not. Here is what I have: private void LoadCompanies(object sender, EventArgs e) { pnlNavigation.ShowLoader(true); this.bgWorker.RunWorkerAsync(); } private delegate object LoadCompaniesDelegate(); public void LoadCompanies(DoWorkEventArgs e) { PROSOCO.Library.Companies.Criteria criteria = PROSOCO.Library.Companies.Criteria.GetCriteria(); BindingSource src = new BindingSource(); PROSOCO.Library.Companies.Nodes nodes = PROSOCO.Library.Companies.Nodes.GetNodes(criteria.NodeCriteria()); src.DataSource = nodes; e.Result = src; } private void bgWorker_DoWork(object sender, DoWorkEventArgs e) { LoadCompanies(e); } private void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { BindingSource src = (BindingSource)e.Result; pnlNavigation.ContentTree.ParentMember = "ParentId"; pnlNavigation.ContentTree.ValueMember = "Id"; pnlNavigation.ContentTree.DisplayMember = "Name"; pnlNavigation.ContentTree.PrefixMember = "CustomerNumber"; pnlNavigation.ContentTree.PostfixMember = "CityState"; pnlNavigation.ContentTree.DataSource = src; pnlNavigation.ShowLoader(false); _activeModule = "Companies"; }

                        P J 2 Replies Last reply
                        0
                        • J Justincc

                          I am new to C# so forgive me for not "just getting it" but this is what I have so far. I am doing something wrong because "BindingSource src = (BindingSource)e.Result;" Doesn't seem to be loading any data... Did I atleast get everything running in the background except the GUI stuff? Can you tell why I wouldn't be loading any data? Thanks in advance. private delegate object LoadCompaniesDelegate(); public object LoadCompanies() { BindingSource src = new BindingSource(); if (pnlNavigation.InvokeRequired) { LoadCompaniesDelegate find = new LoadCompaniesDelegate(LoadCompanies); this.Invoke(find, new object[] { }); } else { PROSOCO.Library.Companies.Criteria criteria = PROSOCO.Library.Companies.Criteria.GetCriteria(); PROSOCO.Library.Companies.Nodes nodes = PROSOCO.Library.Companies.Nodes.GetNodes(criteria.NodeCriteria()); src.DataSource = nodes; MessageBox.Show("Loaded Notes"); } return src; } private void bgWorker_DoWork(object sender, DoWorkEventArgs e) { e.Result = LoadCompanies(); } private void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { BindingSource src = (BindingSource)e.Result; pnlNavigation.ContentTree.ParentMember = "ParentId"; pnlNavigation.ContentTree.ValueMember = "Id"; pnlNavigation.ContentTree.DisplayMember = "Name"; pnlNavigation.ContentTree.PrefixMember = "CustomerNumber"; pnlNavigation.ContentTree.PostfixMember = "CityState"; pnlNavigation.ContentTree.DataSource = src; _activeModule = "Companies"; MessageBox.Show("Completed"); }

                          P Offline
                          P Offline
                          PhilDanger
                          wrote on last edited by
                          #12

                          Remove the --- if (pnlNavigation.InvokeRequired) { LoadCompaniesDelegate find = new LoadCompaniesDelegate(LoadCompanies); this.Invoke(find, new object[] { }); } else { -- Don't touch anything that has to do with a GUI element inside of your background worker DoWork for now... just keep what you have in RunWorkerCompleted. Currently it is taking the first path (InvokeRequired path), so the data won't be loaded into the BindingSource (since that is done in the Else) part.

                          J 2 Replies Last reply
                          0
                          • J Justincc

                            It is still freezing the GUI. Let me know if I am doing this how you reccomended or not. Here is what I have: private void LoadCompanies(object sender, EventArgs e) { pnlNavigation.ShowLoader(true); this.bgWorker.RunWorkerAsync(); } private delegate object LoadCompaniesDelegate(); public void LoadCompanies(DoWorkEventArgs e) { PROSOCO.Library.Companies.Criteria criteria = PROSOCO.Library.Companies.Criteria.GetCriteria(); BindingSource src = new BindingSource(); PROSOCO.Library.Companies.Nodes nodes = PROSOCO.Library.Companies.Nodes.GetNodes(criteria.NodeCriteria()); src.DataSource = nodes; e.Result = src; } private void bgWorker_DoWork(object sender, DoWorkEventArgs e) { LoadCompanies(e); } private void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { BindingSource src = (BindingSource)e.Result; pnlNavigation.ContentTree.ParentMember = "ParentId"; pnlNavigation.ContentTree.ValueMember = "Id"; pnlNavigation.ContentTree.DisplayMember = "Name"; pnlNavigation.ContentTree.PrefixMember = "CustomerNumber"; pnlNavigation.ContentTree.PostfixMember = "CityState"; pnlNavigation.ContentTree.DataSource = src; pnlNavigation.ShowLoader(false); _activeModule = "Companies"; }

                            P Offline
                            P Offline
                            PhilDanger
                            wrote on last edited by
                            #13

                            Stick in some debug statements to see where it is slowing down on.

                            J 1 Reply Last reply
                            0
                            • P PhilDanger

                              Stick in some debug statements to see where it is slowing down on.

                              J Offline
                              J Offline
                              Justincc
                              wrote on last edited by
                              #14

                              I get the (Not Responding) for a couple seconds when it gets to "pnlNavigation.ContentTree.DataSource = src;" This is a lot of data to load, however, I thought the background worker would handle that. Right?

                              1 Reply Last reply
                              0
                              • P PhilDanger

                                Remove the --- if (pnlNavigation.InvokeRequired) { LoadCompaniesDelegate find = new LoadCompaniesDelegate(LoadCompanies); this.Invoke(find, new object[] { }); } else { -- Don't touch anything that has to do with a GUI element inside of your background worker DoWork for now... just keep what you have in RunWorkerCompleted. Currently it is taking the first path (InvokeRequired path), so the data won't be loaded into the BindingSource (since that is done in the Else) part.

                                J Offline
                                J Offline
                                Justincc
                                wrote on last edited by
                                #15

                                Thank you Phil. I still get the (Not Responding) for a couple seconds when it gets to "pnlNavigation.ContentTree.DataSource = src;" This is a lot of data to load. Since it is taking the most time, shouldn't that part be inside bgWorker_DoWork? ... but it cannot because it is updating the GUI ... so I don't konw what to do.

                                1 Reply Last reply
                                0
                                • P PhilDanger

                                  Remove the --- if (pnlNavigation.InvokeRequired) { LoadCompaniesDelegate find = new LoadCompaniesDelegate(LoadCompanies); this.Invoke(find, new object[] { }); } else { -- Don't touch anything that has to do with a GUI element inside of your background worker DoWork for now... just keep what you have in RunWorkerCompleted. Currently it is taking the first path (InvokeRequired path), so the data won't be loaded into the BindingSource (since that is done in the Else) part.

                                  J Offline
                                  J Offline
                                  Justincc
                                  wrote on last edited by
                                  #16

                                  What do you think about this explanation? The freezing is because the control is being filled out by the data source, and the only thread allowed to do that is the UI. So, if your data source is large there isn't a way around the 2 seconds pause... unless... You could manually fill out your control by looping over the data source yourself, and every 10 or so, do a DoEvents() call to keep the UI fresh.

                                  J 1 Reply Last reply
                                  0
                                  • J Justincc

                                    It is still freezing the GUI. Let me know if I am doing this how you reccomended or not. Here is what I have: private void LoadCompanies(object sender, EventArgs e) { pnlNavigation.ShowLoader(true); this.bgWorker.RunWorkerAsync(); } private delegate object LoadCompaniesDelegate(); public void LoadCompanies(DoWorkEventArgs e) { PROSOCO.Library.Companies.Criteria criteria = PROSOCO.Library.Companies.Criteria.GetCriteria(); BindingSource src = new BindingSource(); PROSOCO.Library.Companies.Nodes nodes = PROSOCO.Library.Companies.Nodes.GetNodes(criteria.NodeCriteria()); src.DataSource = nodes; e.Result = src; } private void bgWorker_DoWork(object sender, DoWorkEventArgs e) { LoadCompanies(e); } private void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { BindingSource src = (BindingSource)e.Result; pnlNavigation.ContentTree.ParentMember = "ParentId"; pnlNavigation.ContentTree.ValueMember = "Id"; pnlNavigation.ContentTree.DisplayMember = "Name"; pnlNavigation.ContentTree.PrefixMember = "CustomerNumber"; pnlNavigation.ContentTree.PostfixMember = "CityState"; pnlNavigation.ContentTree.DataSource = src; pnlNavigation.ShowLoader(false); _activeModule = "Companies"; }

                                    J Offline
                                    J Offline
                                    Judah Gabriel Himango
                                    wrote on last edited by
                                    #17

                                    To eliminate possibilities, temporarily comment all code inside RunWorkerCompleted handler. Does it still freeze?

                                    Tech, life, family, faith: Give me a visit. I'm currently blogging about: Orthodox Jews are persecuting Messianic Jews in Israel (video) The apostle Paul, modernly speaking: Epistles of Paul Judah Himango

                                    1 Reply Last reply
                                    0
                                    • J Justincc

                                      What do you think about this explanation? The freezing is because the control is being filled out by the data source, and the only thread allowed to do that is the UI. So, if your data source is large there isn't a way around the 2 seconds pause... unless... You could manually fill out your control by looping over the data source yourself, and every 10 or so, do a DoEvents() call to keep the UI fresh.

                                      J Offline
                                      J Offline
                                      Judah Gabriel Himango
                                      wrote on last edited by
                                      #18

                                      justin.moses wrote:

                                      So, if your data source is large there isn't a way around the 2 seconds pause... unless...

                                      If your data set is too large to be displayed all at once, your best bet is filling the dataset a few rows at a time, preferrably in the Application.Idle event handler. p.s. don't use DoEvents(). It's evil, trust me.

                                      Tech, life, family, faith: Give me a visit. I'm currently blogging about: Orthodox Jews are persecuting Messianic Jews in Israel (video) The apostle Paul, modernly speaking: Epistles of Paul Judah Himango

                                      1 Reply Last reply
                                      0
                                      Reply
                                      • Reply as topic
                                      Log in to reply
                                      • Oldest to Newest
                                      • Newest to Oldest
                                      • Most Votes


                                      • Login

                                      • Don't have an account? Register

                                      • Login or register to search.
                                      • First post
                                        Last post
                                      0
                                      • Categories
                                      • Recent
                                      • Tags
                                      • Popular
                                      • World
                                      • Users
                                      • Groups