Alex Alex - 1 year ago 69 Question

WinForms.IllegalCrossThreadCall with filewatcher

I'm new to Visual Basic and overall kind of new to coding in general.
Currently I work on a program which uses a filewatcher. But If I try this:

Public Class Form1

Private WithEvents fsw As IO.FileSystemWatcher

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
fsw = New IO.FileSystemWatcher("PATH")
fsw.EnableRaisingEvents = True
' fsw.Filter = "*.settings"

End Sub

Private Sub GetSettingsFromFile()
Some Code
More Code
CheckBox1.Checked = True
End Sub

Private Sub fsw_Changed(sender As Object, e As FileSystemEventArgs) Handles fsw.Changed
fsw.EnableRaisingEvents = False 'this is set because the file is changed many times in rapid succesion so I need to stop the Filewatcher from going of 200x (anyone has a better idea to do this?)
fsw.EnableRaisingEvents = True 'enabling it again
End Sub
End Class

But when I do this (trying to change anyhting in the form) I get this error:
System.InvalidOperationException (WinForms.IllegalCrossThreadCall)
It wont stop the program from working, but I want to understand what is wrong here and why the debugger is throwing this at me

Answer Source

The event is being raised on a secondary thread. Any changes to the UI must be made on the UI thread. You need to marshal a method call to the UI thread and update the UI there. Lots of information around on how to do that. Here's an example:

Private Sub UpdateCheckBox1(checked As Boolean)
    If CheckBox1.InvokeRequired Then
        'We are on a secondary thread so marshal a method call to the UI thread.
        CheckBox1.Invoke(New Action(Of Boolean)(AddressOf UpdateCheckBox1), checked)
        'We are on the UI thread so update the control.
        CheckBox1.Checked = checked
    End If
End Sub

Now you simply call that method wherever you are and whatever thread you're on. If you're already on the UI thread then the control will just be updated. If you're on a secondary thread then the method will invoke itself a second time, this time on the UI thread, and the control will be updated in that second invocation.