VB.net избегает межпотокового исключения с помощью метода расширения - PullRequest
1 голос
/ 13 января 2011

Hello Я пытаюсь реализовать решение для обновления элементов управления формы без использования делегата.

Я пытаюсь использовать первое решение на этой странице:

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 или любым ООП.

Я могу заставить работать второе решение на этой странице (используя делегатов), но у меня есть немало вещей, которые нужно сделать в этой теме, и мне кажется, что мне нужно было бы написать новую подпрограмму делегата для каждой вещи, которая кажется расточительной .

Что мне нужно сделать, это выбрать первый элемент в выпадающем списке, обновить текстовый текст textbox.text выбранным элементом и передать выбранный элемент функции. Затем подождите x секунд и начните снова, выбирая второй элемент.

Я могу заставить его работать в однопоточном приложении, но мне нужно, чтобы интерфейс оставался отзывчивым.

Любая помощь с благодарностью.

EDIT: ОК, поэтому изменение синтаксиса сработало для примера. Однако, если я изменю его с

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.

Так теперь я вернулся к тому, с чего начал? Любая дальнейшая помощь очень ценится.

Ответы [ 3 ]

2 голосов
/ 13 января 2011

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

Это синтаксис C #.

Эквивалент VB.NET:

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

... обновление элементов управления формы без использования делегата ...

Just FYI - лямбда-выражение, которое оно использует, являетсяформа делегата.Это просто более удобный синтаксис для объявления и определения делегатов, но здесь вы все еще используете делегатов.

2 голосов
/ 13 января 2011

за ваш второй номер;Я думаю, вам нужно добавить 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 голосов
/ 13 января 2011

Вы путаете синтаксис VB и C #.Ваша лямбда является (почти пропущенными скобками) допустимой C #, но в VB вы должны написать это по-другому:

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

И да, этот синтаксис s * cks.Сожалею.: - (

...