By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,771 Members | 1,669 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,771 IT Pros & Developers. It's quick & easy.

BackgroundWorker thread locking UI

P: n/a
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

Sep 19 '06 #1
Share this Question
Share on Google+
3 Replies


P: n/a
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.
"John Wright" <ri**********@notmail.comwrote in message
news:%2****************@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
Sep 20 '06 #2

P: n/a
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" <ri**********@notmail.comwrote in message
news:%2****************@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
Sep 20 '06 #3

P: n/a
Excellent. This works great. Thanks.

John
"Jay B. Harlow [MVP - Outlook]" <Ja************@tsbradley.netwrote in
message news:CD**********************************@microsof t.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" <ri**********@notmail.comwrote in message
news:%2****************@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.FromSecond s(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

Sep 20 '06 #4

This discussion thread is closed

Replies have been disabled for this discussion.