Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

Using Background worker to fill multiple comboboxes

Posted on 2014-10-26
6
390 Views
Last Modified: 2014-11-16
I have a basic understanding of background worker.  The issue I am having is I do not know how to fill multiple comboboxes in the background worker.  I can fill 1, but when it comes to multiple, the only way I know to do is create multiple background workers.  Any help is greatly appreciated!!  I am using VB.NET not C

   
 Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) _
    Handles BackgroundWorker1.DoWork

        Dim sqluname As String
        Dim sqlpass As String
        Dim sqlseverlocation As String
        Dim sqltable As String
        Dim commtable, communits, commadvisory, commguidecard, commholdingcalls, commdispatchedunits, commclosedcall, commlocation, commstreet, commcity, commactivitycode, commstate, commmethod, commagency, commbolotype, commpaginggroup, Commpagingindividual As String

        If (IO.File.Exists(configfilefromcad)) Then

            'create a new xmltextreader object
            'this is the object that we will loop and will be used to read the xml file
            Dim document As XmlReader = New XmlTextReader(configfilefromcad)

            'loop through the xml file
            While (document.Read())

                Dim type = document.NodeType

                'if node type was element
                If (type = XmlNodeType.Element) Then

                    'if the loop found a <SQLUserName> tag
                    If (document.Name = "SQLUserName") Then

                        sqluname = Decrypt(document.ReadInnerXml.ToString())

                    End If

                    'if the loop found a <SQLPassword> tag
                    If (document.Name = "SQLPassword") Then

                        sqlpass = Decrypt(document.ReadInnerXml.ToString())

                    End If

                    'if the loop found a <SQLServerLocation> tag
                    If (document.Name = "SQLServerLocation") Then

                        sqlseverlocation = Decrypt(document.ReadInnerXml.ToString())

                    End If

                    'if the loop found a <SQLTableName> tag
                    If (document.Name = "SQLTableName") Then

                        sqltable = Decrypt(document.ReadInnerXml.ToString())

                    End If

                    If (document.Name = "AgencyName") Then
                        Dim titlename As String
                        titlename = Decrypt(document.ReadInnerXml.ToString())



                        Me.Text = "Employee Management - " & titlename & " - " & System.Reflection.Assembly.GetExecutingAssembly.GetName.Name()

                    End If

                End If
            End While
            document.Dispose()
        Else

        End If

        Dim cn As New SqlConnection("Server='" + sqlseverlocation + "';Initial Catalog='" + sqltable + "';Persist Security Info=True;User ID='" + sqluname + "';Password='" + sqlpass + "'")

        Dim adap1 As New SqlDataAdapter("Select TextToAdd FROM tblComboBoxEdit WHERE ComBoxNameEdit='Race'", cn)

        Dim dt1 As New DataTable

       adap1.Fill(dt1)

        Dim Unit = dt1.AsEnumerable().Select(Function(d) DirectCast(d(0).ToString(), Object)).ToArray()

       Me.BackgroundWorker1.ReportProgress(0, Unit)

        cn.Close()

    End Sub

    Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As System.Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs)   Handles BackgroundWorker1.ProgressChanged

        txtrace.Items.Clear()
        txtrace.Items.AddRange(e.UserState)

    End Sub

Open in new window

0
Comment
Question by:russell12
6 Comments
 
LVL 40
ID: 40405828
You have it right. A BackgroundWorker can do only one thing at a time, so you need many of them if you want to do many jobs at the same time.
0
 
LVL 2

Author Comment

by:russell12
ID: 40409600
Thank you for your input.  I read online that too many background workers can cause a good deal of lag.  I have about 10 comboboxes that need to be filled at Form_Load.  Do you know if this is a true statement?  I have found a work around, but it is not a "good" work around.  I am using the background thread to work with the gui and update a label.  Thank you for your input.
Russell
0
 
LVL 40

Assisted Solution

by:Jacques Bourgeois (James Burger)
Jacques Bourgeois (James Burger) earned 167 total points
ID: 40409822
Yes you will feel the lag. A BackgroundWorker is just an easy way to start a new thread. Each BackgroundWorker starts its own thread.

A computer can do only one thing at a time, unless something in the program manages the use of multiple cores in modern processors, which as far as I know the compiler does not do automatically.

Since it does one thing at a time, in order to make the threads run in parallel, the computer simply allows little slots of time to each one in turn. This involves more work, because it needs to reminds where each thread is paused in order to restart from the right place it when its turn comes again. This switching between threads slows down things.

Using numerous threads (BackgroundWorkers) always slows down things. You never use that to speed up things, but only to give the impression that things are going faster. The name given to the control says it all. You use that for background work, not for work that happens in the forefront. For instance, if the form has its multiple ComboBoxes on different tabs, you could first load the ones on the tab that shows first. Then, while the user is working on that tab, use a BackgroundWorker to load the tabs that are not shown yet. That way the first tab shows fast because it does not have to wait for all the other ones to be ready. The user being a lot slower than the computer, he won't feel the slow down created by the BackgroundWorkers while they fill the other tabs. But when he switches to another tab, it's very fast because it was already loaded in the background.

If all the ComboBoxes are on the same tab, form, page, you lose by using BackgroundWorkers. If the user always perform the same sequence of operations, you might want to load the portion of the data that he uses first, and load the rest with a BackgroundWorker while he starts working, keeping the controls disabled until they are ready to work. But if all the information has to be available right from the start, they you are better to do the job sequentially.

One thing you can do then, to give the impression that things are going faster, is to show something on the screen while you are loading your form. A simple MessageBox, or maybe better, a splash screen. When the users sees something, he fills that the computer is working. Otherwise, he is only waiting and it seems to take long.
0
Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

 
LVL 83

Accepted Solution

by:
CodeCruiser earned 167 total points
ID: 40411256
If all your comboboxes require the amount of code that you currently have in your backgroundworker, I would suggest adding a method for populating each combobox and then calling those methods from the same backgroundworker.
0
 
LVL 28

Assisted Solution

by:Ark
Ark earned 166 total points
ID: 40415383
As I can see you'r using ReportProgress vs ProgressChange Event to fill combobox. e.UserState is an object backgroundworker pass to gui. Now you'r using an array of object, but it can be ANY type, for example a dictionary:
Inside bgworker_dowork:
Dim dict As New Dictionary(Of String,Object())
'....
dict.Add(MyFirstComboName, dt1.AsEnumerable().Select(Function(d) DirectCast(d(0).ToString(), Object)).ToArray())
dict.Add(MySecondComboName, dt2.AsEnumerable().Select(Function(d) DirectCast(d(0).ToString(), Object)).ToArray())
'or whatever data to fill each combo

Open in new window

Then, in _ProgressChanged event
Dim dict = CType(e.UserState, Dictionary(Of String, Object()))
For Each key in dict.Keys
    Dim cbo As ComboBox = Me.Controls(key) 
    cbo.Items.Clear()
    cbo.Items.AddRange(dict(key))
Next

Open in new window

0
 
LVL 2

Author Closing Comment

by:russell12
ID: 40445926
Sorry for taking so long to repsond.  Thanks for all of your help!
0

Featured Post

Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
MVC DDL Json Not Binding to Model 2 25
C# LINQ ForEach() question 6 48
VB.NET String Settings and Temp Folder Question 3 51
run a stored procedure from vb.net 1 27
Welcome my friends to the second instalment and follow-up to our Minify and Concatenate Your Scripts and Stylesheets (http://www.experts-exchange.com/Programming/Languages/.NET/ASP.NET/A_4334-Minify-and-Concatenate-Your-Scripts-and-Stylesheets.html)…
The ECB site provides FX rates for major currencies since its inception in 1999 in the form of an XML feed. The files have the following format (reducted for brevity) (CODE) There are three files available HERE (http://www.ecb.europa.eu/stats/exch…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

790 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question