To able to do proper cross-thread access I’m using a piece of code something like this :
Private Delegate Sub DelSetButton(ByVal button As Button, ByVal label As String, ByVal enabled As Boolean) Private Sub SetButton(ByVal button As Button, ByVal label As String, ByVal enabled As Boolean) If InvokeRequired Then Invoke(New DelSetButton(AddressOf SetButton), button, label, enabled) Else button.Enabled = enabled button.Text = label End If End Sub
Which is not lovely.
- I have to create a delegate with the same signature
- I need to write a similar call for each control type or each action I want
I’m using VB.NET 9 / .NET Framework 3.5.
Is there any better way to do it? Or am I stuck with this model?
UPDATE :
After the answers I like this one best :
Private Sub ContSetButton(ByVal button As Button, ByVal label As String, ByVal enabled As Boolean) Invoke(New Action(Of Button, String, Boolean)(AddressOf SetButton), button, label, enabled) End Sub Private Sub SetButton(ByVal button As Button, ByVal label As String, ByVal Enabled As Boolean) button.Text = label button.Enabled = Enabled End Sub
Still not perfect but better than what I’ve done originally.
Feel free to answer if you can make it better than this.
(This is assuming you need more detailed control than
BackgroundWorkerprovides – if that’s enough for you, it’s the right answer, as suggested by Mehrdad Afshari.)You don’t need to create a delegate type. Use the generic
FuncandActiontypes.Rather than testing for InvokeRequired, you might want to just have two methods – one which always invokes, and then an ‘Impl’ (or whatever) method which is only ever called on the UI thread and doesn’t do any invoking. It’s a change to the pattern rather than a new pattern, but it may be a bit cleaner.
It should be possible to write a more general way of handling this, but it’ll take a little bit of time for me to think it through… and I’d be presenting it in C# rather than VB, too…