Reputation: 423
When I try to load a form with a backgroundworker class, it throws an exception because I tried to access an object that was created by another thread, not by the current thread. How to load that form by backgroundworker ?
(I am looking for marquee progress bar while the form is loading)
Upvotes: 4
Views: 8076
Reputation: 770
You cannot do this. Forms have Thread-Affinity. ie. they can ONLY be accessed by the thread that instantiated the Form. You background thread just became the UI thread for the form! So what you MUST do is marshal the call onto the correct thread. Test InvokeRequired. If true, instantiate a delegate, call BeginInvoke and IMMEDIATELY return. Now the call will be marshaled to the correct thread.
Upvotes: 0
Reputation: 25464
There is no problem to initialize the second form in another thread, but if you want to use it in the context on your main form, you have to use original thread. The follows code creates and initializes new form in background worker and then shows it when initialization is completed in appropriate event handler:
Public Class Form1
Dim form2 As Form2
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
BackgroundWorker1.RunWorkerAsync()
End Sub
Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
form2 = New Form2()
form2.TextBox1.Text = "Text"
End Sub
Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
form2.Show()
End Sub
End Class
You can use ProgressChanged event of background worker for the purpose of report to progress bar.
Upvotes: 0
Reputation: 1096
You can't change any controls in the DoWork section of a backgroundworker since it's a separate thread. You'll want to process any data in the DoWork section, then update your form in the RunWorkerCompleted section.
Example:
Private WithEvents bgwTasks As New BackgroundWorker
Private Sub bgwTasks_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bgwTasks.DoWork
e.Result= GetDatabaseTable()
End Sub
Private Sub bgwTasks_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bgwTasks.RunWorkerCompleted
If e.Result IsNot Nothing Then
DataGridView1.DataSource = e.Result
End If
End Sub
Private Sub Main_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
If bgwTasks.IsBusy = False Then
bgwTasks.RunWorkerAsync()
End If
End Sub
Upvotes: 2
Reputation: 1824
This will disable checking for Cross Threads
Me.CheckForIllegalCrossThreadCalls = False
I still suggest you search for Cross Thread regarding the proper use of the BackgroundWorker Class.
Upvotes: 0