2011-01-13 92 views
1

你好 我想實現一個解決方案來更新表單控件而不使用委託。VB.net避免與擴展方法的交叉線程異常

我試圖使用此頁面上的第一個解決方案:

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. 

那麼現在我回到我開始的地方? 任何進一步的幫助非常感謝。

+0

謝謝,愚蠢的錯誤在那裏。 – Steve 2011-01-13 20:33:25

回答

1

您的第二個問題;我認爲你需要添加一個其他的:

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 
+0

謝謝,就是這樣。真的應該注意到了。至少在學習一些東西! – Steve 2011-01-13 20:56:12

2

令人困惑的VB和C#語法。你拉姆達(幾乎,缺少大括號)有效的C#,但在VB中你必須寫這個是不同的:

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

是的,這句法S *中正。抱歉。 :-(

2

Label1.CustomInvoke(L => l.Text =的 「Hello World!」)

這是C#語法

的VB.NET等效爲:

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

...不使用委託更新表單控件...

只是FYI - 一個lambda表達式,這正是使用,是一種委託形式。這只是用於聲明和定義委託的更方便的語法 - 但您仍然在此處使用委託。