|
web
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
BackgroundWorker thread locking UIthat are connected. I have a delegate that I call that invokes a procdure that loads a dataset with computer names and then attaches it to a dropdown. When I run it, my UI freezes until it completes. Any thoughts on how to do this without freezing the UI? John Code 'General Declaration Private Delegate Sub LoadComputerDelegate() 'called from form load bgLoadComputers.RunWorkerAsync() 'sub that does the work Private Sub bgLoadComputers_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bgLoadComputers.DoWork tsStatus.Text = "Loading Computers. Please wait..." System.Threading.Thread.Sleep(TimeSpan.FromSeconds(2)) Invoke(New LoadComputerDelegate(AddressOf LoadComputerDropDown)) End Sub Private Sub LoadComputerDropDown() 'get the computers on the domain Try Dim enTry As DirectoryEntry = New DirectoryEntry(LDAP://[MYDOMAIN]) Dim mySearcher As DirectorySearcher = New DirectorySearcher(enTry) mySearcher.Filter = ("(objectClass=Computer)") Dim resEnt As SearchResult For Each resEnt In mySearcher.FindAll Try Dim tmpID As String = Mid(resEnt.GetDirectoryEntry.Name.ToString, 4) If Mid(tmpID, 1, 2) = "L1" Then Dim rwComputer As DataRow rwComputer = dtComputers.NewRow rwComputer("Computer Name") = (Mid((resEnt.GetDirectoryEntry().Name.ToString), 4)) dtComputers.Rows.Add(rwComputer) End If tsStatus.Text = "Computers Loaded..." cboDomainComuters.DataSource = dtComputers cboDomainComuters.DisplayMember = "Computer Name" Catch ex As Exception End Try Next Catch ex As Exception End Try End Sub John,
You need to do the actual work in the DoWork event handler. I would call LoadComputerDropDown directly from DoWork, when LoadComputerDropDown completes I would Invoke a method on the UI that "returns" the dataset... Something like: 'Code Private Delegate Sub LoadComputerDelegate(ByVal table As DataTable) 'called from form load Protected Overrides Sub OnLoad(ByVal e As System.EventArgs) MyBase.OnLoad(e) tsStatus.Text = "Loading Computers. Please wait..." bgLoadComputers.RunWorkerAsync() End Sub 'sub that does the work Private Sub bgLoadComputers_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bgLoadComputers.DoWork System.Threading.Thread.Sleep(TimeSpan.FromSeconds(2)) LoadComputerDropDown() End Sub Private Sub LoadComputerDropDown() Dim dtComputers As New DataTable("Computers") dtComputers.Columns.Add("Computer Name", GetType(String)) 'get the computers on the domain Try Dim enTry As DirectoryEntry = New DirectoryEntry("LDAP://TSBRADLEY") Dim mySearcher As DirectorySearcher = New DirectorySearcher(enTry) mySearcher.Filter = ("(objectClass=Computer)") Dim resEnt As SearchResult For Each resEnt In mySearcher.FindAll Try Dim tmpID As String = Mid(resEnt.GetDirectoryEntry.Name.ToString, 4) If Mid(tmpID, 1, 2) = "L1" Then Dim rwComputer As DataRow rwComputer = dtComputers.NewRow rwComputer("Computer Name") = (Mid((resEnt.GetDirectoryEntry().Name.ToString), 4)) dtComputers.Rows.Add(rwComputer) End If Invoke(New LoadComputerDelegate(AddressOf SetDomainComuters), dtComputers) Catch ex As Exception Invoke(New LoadComputerDelegate(AddressOf SetDomainComuters), dtComputers) End Try Next Catch ex As Exception Invoke(New LoadComputerDelegate(AddressOf SetDomainComuters), dtComputers) End Try End Sub Private Sub SetDomainComuters(ByVal dtComputers As DataTable) tsStatus.Text = "Computers Loaded..." cboDomainComuters.DataSource = dtComputers cboDomainComuters.DisplayMember = "Computer Name" End Sub Note: You should not refer to controls (tsStatus) from the DoWork method. Show quoteHide quote "John Wright" <riley_wri***@notmail.com> wrote in message news:%23YWVgwC3GHA.4172@TK2MSFTNGP05.phx.gbl... >I have a background worker thread that scans the network listing computers >that are connected. I have a delegate that I call that invokes a procdure >that loads a dataset with computer names and then attaches it to a >dropdown. When I run it, my UI freezes until it completes. Any thoughts on >how to do this without freezing the UI? > > John > > > Code > > 'General Declaration > > Private Delegate Sub LoadComputerDelegate() > > 'called from form load > > bgLoadComputers.RunWorkerAsync() > > > > 'sub that does the work > > Private Sub bgLoadComputers_DoWork(ByVal sender As System.Object, ByVal e > As System.ComponentModel.DoWorkEventArgs) Handles bgLoadComputers.DoWork > > tsStatus.Text = "Loading Computers. Please wait..." > > System.Threading.Thread.Sleep(TimeSpan.FromSeconds(2)) > > Invoke(New LoadComputerDelegate(AddressOf LoadComputerDropDown)) > > End Sub > > Private Sub LoadComputerDropDown() > > 'get the computers on the domain > > Try > > Dim enTry As DirectoryEntry = New DirectoryEntry(LDAP://[MYDOMAIN]) > > Dim mySearcher As DirectorySearcher = New DirectorySearcher(enTry) > > mySearcher.Filter = ("(objectClass=Computer)") > > Dim resEnt As SearchResult > > For Each resEnt In mySearcher.FindAll > > Try > > Dim tmpID As String = Mid(resEnt.GetDirectoryEntry.Name.ToString, 4) > > If Mid(tmpID, 1, 2) = "L1" Then > > Dim rwComputer As DataRow > > rwComputer = dtComputers.NewRow > > rwComputer("Computer Name") = > (Mid((resEnt.GetDirectoryEntry().Name.ToString), 4)) > > dtComputers.Rows.Add(rwComputer) > > End If > > tsStatus.Text = "Computers Loaded..." > > cboDomainComuters.DataSource = dtComputers > > cboDomainComuters.DisplayMember = "Computer Name" > > Catch ex As Exception > > End Try > > Next > > Catch ex As Exception > > End Try > > End Sub > > > John,
Doh! You don't need the delegate or the Invoke, the "beauty" of the background work thread is that it handles the communication between both threads for you. Something like: 'called from form load Protected Overrides Sub OnLoad(ByVal e As System.EventArgs) MyBase.OnLoad(e) tsStatus.Text = "Loading Computers. Please wait..." bgLoadComputers.RunWorkerAsync() End Sub 'sub that does the work Private Sub bgLoadComputers_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bgLoadComputers.DoWork System.Threading.Thread.Sleep(TimeSpan.FromSeconds(2)) e.Result = LoadComputerDropDown() End Sub Private Function LoadComputerDropDown() As DataTable Dim dtComputers As New DataTable("Computers") dtComputers.Columns.Add("Computer Name", GetType(String)) 'get the computers on the domain Dim enTry As DirectoryEntry = New DirectoryEntry("LDAP://[MYDOMAIN]) Dim mySearcher As DirectorySearcher = New DirectorySearcher(enTry) mySearcher.Filter = ("(objectClass=Computer)") Dim resEnt As SearchResult For Each resEnt In mySearcher.FindAll Dim tmpID As String = Mid(resEnt.GetDirectoryEntry.Name.ToString, 4) If Mid(tmpID, 1, 2) = "L1" Then Dim rwComputer As DataRow rwComputer = dtComputers.NewRow rwComputer("Computer Name") = (Mid((resEnt.GetDirectoryEntry().Name.ToString), 4)) dtComputers.Rows.Add(rwComputer) End If Next Return dtComputers End Function Private Sub bgLoadComputers_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bgLoadComputers.RunWorkerCompleted If e.Error Is Nothing Then tsStatus.Text = "Computers Loaded..." cboDomainComuters.DataSource = e.Result cboDomainComuters.DisplayMember = "Computer Name" Else MessageBox.Show(e.Error.ToString(), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error) End If End Sub -- Show quoteHide quoteHope this helps Jay B. Harlow [MVP - Outlook] ..NET Application Architect, Enthusiast, & Evangelist T.S. Bradley - http://www.tsbradley.net "John Wright" <riley_wri***@notmail.com> wrote in message news:%23YWVgwC3GHA.4172@TK2MSFTNGP05.phx.gbl... >I have a background worker thread that scans the network listing computers >that are connected. I have a delegate that I call that invokes a procdure >that loads a dataset with computer names and then attaches it to a >dropdown. When I run it, my UI freezes until it completes. Any thoughts on >how to do this without freezing the UI? > > John > > > Code > > 'General Declaration > > Private Delegate Sub LoadComputerDelegate() > > 'called from form load > > bgLoadComputers.RunWorkerAsync() > > > > 'sub that does the work > > Private Sub bgLoadComputers_DoWork(ByVal sender As System.Object, ByVal e > As System.ComponentModel.DoWorkEventArgs) Handles bgLoadComputers.DoWork > > tsStatus.Text = "Loading Computers. Please wait..." > > System.Threading.Thread.Sleep(TimeSpan.FromSeconds(2)) > > Invoke(New LoadComputerDelegate(AddressOf LoadComputerDropDown)) > > End Sub > > Private Sub LoadComputerDropDown() > > 'get the computers on the domain > > Try > > Dim enTry As DirectoryEntry = New DirectoryEntry(LDAP://[MYDOMAIN]) > > Dim mySearcher As DirectorySearcher = New DirectorySearcher(enTry) > > mySearcher.Filter = ("(objectClass=Computer)") > > Dim resEnt As SearchResult > > For Each resEnt In mySearcher.FindAll > > Try > > Dim tmpID As String = Mid(resEnt.GetDirectoryEntry.Name.ToString, 4) > > If Mid(tmpID, 1, 2) = "L1" Then > > Dim rwComputer As DataRow > > rwComputer = dtComputers.NewRow > > rwComputer("Computer Name") = > (Mid((resEnt.GetDirectoryEntry().Name.ToString), 4)) > > dtComputers.Rows.Add(rwComputer) > > End If > > tsStatus.Text = "Computers Loaded..." > > cboDomainComuters.DataSource = dtComputers > > cboDomainComuters.DisplayMember = "Computer Name" > > Catch ex As Exception > > End Try > > Next > > Catch ex As Exception > > End Try > > End Sub > > > Excellent. This works great. Thanks.
John Show quoteHide quote "Jay B. Harlow [MVP - Outlook]" <Jay_Harlow_***@tsbradley.net> wrote in message news:CD01013B-EC1D-462D-BEFE-BD0EB87624C3@microsoft.com... > John, > Doh! You don't need the delegate or the Invoke, the "beauty" of the > background work thread is that it handles the communication between both > threads for you. > > Something like: > > 'called from form load > > Protected Overrides Sub OnLoad(ByVal e As System.EventArgs) > MyBase.OnLoad(e) > tsStatus.Text = "Loading Computers. Please wait..." > bgLoadComputers.RunWorkerAsync() > End Sub > > > > 'sub that does the work > > Private Sub bgLoadComputers_DoWork(ByVal sender As System.Object, ByVal > e As System.ComponentModel.DoWorkEventArgs) Handles bgLoadComputers.DoWork > System.Threading.Thread.Sleep(TimeSpan.FromSeconds(2)) > e.Result = LoadComputerDropDown() > End Sub > > Private Function LoadComputerDropDown() As DataTable > Dim dtComputers As New DataTable("Computers") > dtComputers.Columns.Add("Computer Name", GetType(String)) > 'get the computers on the domain > Dim enTry As DirectoryEntry = New > DirectoryEntry("LDAP://[MYDOMAIN]) > Dim mySearcher As DirectorySearcher = New DirectorySearcher(enTry) > mySearcher.Filter = ("(objectClass=Computer)") > Dim resEnt As SearchResult > For Each resEnt In mySearcher.FindAll > Dim tmpID As String = > Mid(resEnt.GetDirectoryEntry.Name.ToString, 4) > If Mid(tmpID, 1, 2) = "L1" Then > Dim rwComputer As DataRow > rwComputer = dtComputers.NewRow > rwComputer("Computer Name") = > (Mid((resEnt.GetDirectoryEntry().Name.ToString), 4)) > dtComputers.Rows.Add(rwComputer) > End If > Next > Return dtComputers > End Function > > Private Sub bgLoadComputers_RunWorkerCompleted(ByVal sender As Object, > ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles > bgLoadComputers.RunWorkerCompleted > If e.Error Is Nothing Then > tsStatus.Text = "Computers Loaded..." > cboDomainComuters.DataSource = e.Result > cboDomainComuters.DisplayMember = "Computer Name" > Else > MessageBox.Show(e.Error.ToString(), Application.ProductName, > MessageBoxButtons.OK, MessageBoxIcon.Error) > End If > End Sub > > > -- > Hope this helps > Jay B. Harlow [MVP - Outlook] > .NET Application Architect, Enthusiast, & Evangelist > T.S. Bradley - http://www.tsbradley.net > > > > "John Wright" <riley_wri***@notmail.com> wrote in message > news:%23YWVgwC3GHA.4172@TK2MSFTNGP05.phx.gbl... >>I have a background worker thread that scans the network listing computers >>that are connected. I have a delegate that I call that invokes a procdure >>that loads a dataset with computer names and then attaches it to a >>dropdown. When I run it, my UI freezes until it completes. Any thoughts >>on how to do this without freezing the UI? >> >> John >> >> >> Code >> >> 'General Declaration >> >> Private Delegate Sub LoadComputerDelegate() >> >> 'called from form load >> >> bgLoadComputers.RunWorkerAsync() >> >> >> >> 'sub that does the work >> >> Private Sub bgLoadComputers_DoWork(ByVal sender As System.Object, ByVal e >> As System.ComponentModel.DoWorkEventArgs) Handles bgLoadComputers.DoWork >> >> tsStatus.Text = "Loading Computers. Please wait..." >> >> System.Threading.Thread.Sleep(TimeSpan.FromSeconds(2)) >> >> Invoke(New LoadComputerDelegate(AddressOf LoadComputerDropDown)) >> >> End Sub >> >> Private Sub LoadComputerDropDown() >> >> 'get the computers on the domain >> >> Try >> >> Dim enTry As DirectoryEntry = New DirectoryEntry(LDAP://[MYDOMAIN]) >> >> Dim mySearcher As DirectorySearcher = New DirectorySearcher(enTry) >> >> mySearcher.Filter = ("(objectClass=Computer)") >> >> Dim resEnt As SearchResult >> >> For Each resEnt In mySearcher.FindAll >> >> Try >> >> Dim tmpID As String = Mid(resEnt.GetDirectoryEntry.Name.ToString, 4) >> >> If Mid(tmpID, 1, 2) = "L1" Then >> >> Dim rwComputer As DataRow >> >> rwComputer = dtComputers.NewRow >> >> rwComputer("Computer Name") = >> (Mid((resEnt.GetDirectoryEntry().Name.ToString), 4)) >> >> dtComputers.Rows.Add(rwComputer) >> >> End If >> >> tsStatus.Text = "Computers Loaded..." >> >> cboDomainComuters.DataSource = dtComputers >> >> cboDomainComuters.DisplayMember = "Computer Name" >> >> Catch ex As Exception >> >> End Try >> >> Next >> >> Catch ex As Exception >> >> End Try >> >> End Sub >> >> >> > |
|||||||||||||||||||||||