Windows Develop Bookmark and Share   
 index > Windows Forms General > BackgroundWorker thread problem
 

BackgroundWorker thread problem

Hello,

I was using a backgroundworker to load some data into a datagrid, so it does a select query, and I set the datasource of a datagrid.  But I got an error saying that the backgroundworker was working on the same thread as the application:

Cross-thread operation not valid: Control 'dgvData' accessed from a thread other than the thread it was created on.

How do I establish the backgroundworker on another thread?

Thanks.
Brian Mains  Tuesday, November 08, 2005 5:18 PM
You're not right. Read carefully error message.

The error is saying that you're trying to access control (created in main thread) "from the thread other then thread it was created on". To access Windows Forms control from another thread you have to use Control.Invoke method.
Igor Sukhov  Tuesday, November 08, 2005 11:21 PM

I'm sure it's because I'm not right.  I have to learn more about threading, and I'm not familiar with Control.Invoke.  I have this code:

Private Sub bwWorker_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bwWorker.DoWork

Dim objConnection As SqlConnection = Nothing

Dim objAdapter As SqlDataAdapter = Nothing

Dim dtbData As DataTable = Nothing

Try

objConnection = New SqlConnection(ConnectionStrings("DAS").ConnectionString)

objAdapter = New SqlDataAdapter(e.Argument.ToString(), objConnection)

objAdapter.SelectCommand.CommandType = CommandType.Text

dtbData = New DataTable

objAdapter.Fill(dtbData)

dgvData.DataSource = dtbData

dgvData.Refresh()

Finally

dtbData = Nothing

objAdapter = Nothing

objConnection = Nothing

End Try

End Sub

The work done by the background worker queries a database and fills a datagrid; I'm doing this because I have a lot of data to load at times.  So, using this approach, how do I implement Control.Invoke?

Let me know if you need more information.

Thanks.

Brian Mains  Wednesday, November 09, 2005 1:50 PM

First of all your Finally block is wrong. You need to change it on the following:

Finnally

objConnection.Close()

End Try

You don't need those extra lines.

About your error:

You getting an error in "dgvData.DataSource = dtbData" line.You can't set any setting to any control in BackgroundWorker.DoWork method, so you need to Invoke it.

Use folowing method instead of "dgvData.DataSource = dtbData":

Private Sub SetDataSource(ByVal dtbData as DataTable)

if(dgvData.InvokeRequired) then

Dim del as DataSourceHandler = new DataSourceHandler(AddressOf SetDataSource)

Dim objects(dtbData) as Object

dgvData.Invoke(del, objects)

else

dgvData.DataSource = dtbData

end if

End Sub

Public Delegate Sub DataSourceHandler (ByVal dtbData as DataTable)

Kiforl  Friday, November 17, 2006 7:46 AM
It might be easier to pass the DataTable object in the DoWorkEventArgs argument and to populate the DataGridView control in a RunWorkerCompleted event handler...
nobugz  Friday, November 17, 2006 2:31 PM

Anything in theRunWorkCompleted event(and also the Progress event) will already be executing on the correct thread.

The whole purpose of the BackgroundWorker class is so that you dont have to worry about Control.Invoke().

Keith Rome  Friday, November 17, 2006 4:02 PM

You can use google to search for other answers

Custom Search

More Threads

• PropertyGrid Control displays object name, rather than string value
• How to change selected index of combobox using Win API?
• opengl objects on CLR window
• MDI Child closed but MDI parent think other
• Multiple forms with 1 display at taskbar
• use part of name from one object as name for another object
• GDI32 problem
• WebBrowser Control NavigateError event
• The destination thread no longer exists.
• problems when passing data through window forrms