问题
Hello I am trying to implement a solution for updating form controls without using a delegate.
I am attempting to use the 1st solution on this page:
http://www.dreamincode.net/forums/blog/143/entry-2337-handling-the-dreaded-cross-thread-exception/
Imports System.ComponentModel
Imports System.Runtime.CompilerServices
Public Module MyInvoke
<Extension()> _
Public Sub CustomInvoke(Of T As ISynchronizeInvoke)(ByVal control As T, ByVal toPerform As Action(Of T))
If control.InvokeRequired Then
control.Invoke(toPerform, New Object() {control})
toPerform(control)
End If
End Sub
End Module
The site gives this as example of how to use:
Label1.CustomInvoke(l => l.Text = "Hello World!")
But i get 'l' is not declared error. As you can see im very new to VB or any OOP.
I can get the second solution on that page to work (using delegates) but i have quite a few things to do in this thread and it seems like i would need to write a new delegate sub for each thing, which seems wasteful.
What i need to do is select the 1st item from a combobox, update a textbox.text with the selected item, and pass the selected item to a function. Then wait for x seconds and start again, selecting the second item.
I can get it to work in a single threaded application, but i need the interface to remain responsive.
Any help greatly appreciated.
EDIT: OK so changing the syntax worked for the example. However if i change it from
Label1.CustomInvoke(Sub(l) l.text = "hello world!")
(which worked just fine) to:
Dim indexnumber As Integer = 0
ComboBox1.CustomInvoke(Sub(l) l.SelectedIndex = indexnumber)
I get a cross threading error as though i didnt even use this method:
Cross-thread operation not valid: Control 'ComboBox1' accessed from a thread other than the thread it was created on.
So now im back to where i started? Any further help very much appreciated.
回答1:
Per your second issue; I think you need to add an Else:
Public Sub CustomInvoke(Of T As ISynchronizeInvoke)(ByVal control As T, ByVal toPerform As Action(Of T))
If control.InvokeRequired Then
control.Invoke(toPerform, New Object() {control})
Else
' ^^^^
toPerform(control)
End If
End Sub
回答2:
You’re confusing VB and C# syntax. Your lambda is (almost, missing braces) valid C# but in VB you must write this differently:
Label1.CustomInvoke(Sub (l) l.Text = "Hello World!")
And yes, this syntax s*cks. Sorry. :-(
回答3:
Label1.CustomInvoke(l => l.Text = "Hello World!")
This is C# syntax.
The VB.NET equivalent is:
Label1.CustomInvoke( Sub(l) l.Text = "Hello World!" )
... updating form controls without using a delegate...
Just FYI - A lambda expression, which is what this is using, is a form of delegate. It's just a more convenient syntax for declaring and defining delegates - but you're still using delegates here.
来源:https://stackoverflow.com/questions/4683473/vb-net-avoiding-cross-thread-exception-with-extension-method