VB.net avoiding cross thread exception with extension method

北城以北 提交于 2019-12-23 03:01:11

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!