VB.net通过扩展方法避免跨线程异常

发布于 2024-10-11 13:53:36 字数 1567 浏览 6 评论 0原文

你好 我正在尝试实现一种在不使用委托的情况下更新表单控件的解决方案。

我正在尝试使用此页面上的第一个解决方案:

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

该网站给出了这个示例使用:

Label1.CustomInvoke(l => l.Text = "Hello World!")

但我得到“l”未声明错误。 正如你所看到的,我对 VB 或任何 OOP 都很陌生。

我可以让该页面上的第二个解决方案工作(使用委托),但我在这个线程中有很多事情要做,似乎我需要为每件事编写一个新的委托子,这似乎很浪费。

我需要做的是从组合框中选择第一个项目,用所选项目更新 textbox.text,然后将所选项目传递给函数。 然后等待 x 秒并重新开始,选择第二个项目。

我可以让它在单线程应用程序中工作,但我需要界面保持响应。

非常感谢任何帮助。

编辑: 好的,更改语法适用于该示例。 但是,如果我将其从

Label1.CustomInvoke(Sub(l) l.text = "hello world!")

(效果很好)更改为:

Dim indexnumber As Integer = 0
ComboBox1.CustomInvoke(Sub(l) l.SelectedIndex = indexnumber)

我收到交叉线程错误,就好像我什至没有使用此方法一样:

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

那么现在我回到了我开始的地方? 非常感谢任何进一步的帮助。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

等往事风中吹 2024-10-18 13:53:36

根据你的第二期;我认为你需要添加一个 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 

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 
︶ ̄淡然 2024-10-18 13:53:36

您混淆了 VB 和 C# 语法。你的 lambda 是(几乎缺少大括号)有效的 C#,但在 VB 中你必须以不同的方式编写它:

Label1.CustomInvoke(Sub (l) l.Text = "Hello World!")

是的,这种语法很糟糕。对不起。 :-(

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. :-(

吃→可爱长大的 2024-10-18 13:53:36

Label1.CustomInvoke(l => l.Text = "Hello World!")

这是 C# 语法。

VB.NET 的等价物是:

Label1.CustomInvoke( Sub(l) l.Text = "Hello World!" )

...在不使用委托的情况下更新表单控件...

仅供参考 - 这是使用的 lambda 表达式,是委托的一种形式。它只是声明和定义委托的更方便的语法 - 但您仍然在这里使用委托。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文