Question Accessing GUI from thread?

littlebigman

Well-known member
Joined
Jan 5, 2010
Messages
75
Programming Experience
Beginner
Hello

I need to write an application that will download a few web pages. The action is launched by clicking on Button1.

To avoid freezing the UI, I use a Background Worker.

To prevent the user from clicking the button again while the pages are being downloaded, I'd like to disable the button.

However, re-enabling the button in BackgroundWorker1_RunWorkerCompleted() triggers this error:

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

What would be a good way to solve this?

Thank you.

PS: Here's the basic code:

VB.NET:
Imports System.Net
Imports System.IO

Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        BackgroundWorker1.WorkerReportsProgress = True
        BackgroundWorker1.RunWorkerAsync()
    End Sub

    Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        While (True)
            Try
                'perform some lenghty process here

                Exit While
            Catch ex As Exception
                BackgroundWorker1.ReportProgress(100, ex.Message)
            End Try
            System.Threading.Thread.Sleep(2000)
        End While
    End Sub

    Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
        MessageBox.Show("Done!")
        
        'Cross-thread operation not valid: Control 'Button1' accessed from a thread other than the thread it was created on
        Button1.Enabled = True
    End Sub
End Class
 
Something is seriously wrong there. That should absolutely not be happening. The whole point of the RunWorkerCompleted event is to allow you to update the UI when the work is complete. The event is specifically raised on the UI thread for that purpose. Unless you're creating a new Button in the DoWork event handler and assigning it to the Button1 field, I think that your project is corrupted in some way. I would suggest creating a new project and testing the same scenario to see if it behaves the same way. If it doesn't then you might just have to discard the old project, otherwise you may need to repair something.
 
Something is seriously wrong there. That should absolutely not be happening. The whole point of the RunWorkerCompleted event is to allow you to update the UI when the work is complete. The event is specifically raised on the UI thread for that purpose. Unless you're creating a new Button in the DoWork event handler and assigning it to the Button1 field, I think that your project is corrupted in some way. I would suggest creating a new project and testing the same scenario to see if it behaves the same way. If it doesn't then you might just have to discard the old project, otherwise you may need to repair something.

Thanks for the feedback. I'll read up on RunWorker and async web downloads to figure it out.
 
Back
Top