Странная межпоточная проблема WPF

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

Я знаю, что при попытке получить доступ к свойству элемента управления в потоке пользовательского интерфейса из другого потока требуется вызов, но я столкнулся с проблемой с событием, которое дает мне старую ошибку «The calling thread cannot access this object because a different thread owns it.».

Теперь у меня сложилось впечатление, что событие происходит в потоке пользовательского интерфейса, и поэтому не должно быть проблем с таким исключением перекрестного потока... Вот мой XML:

<MenuItem Header="Search Both" Foreground="Black">
    <TextBox
        Name="SearchBothBox"
        Height="23"
        Width="120"/>

А вот код связанного события нажатия клавиши:

Private Sub SearchBothBox_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Input.KeyEventArgs) Handles SearchBothBox.KeyDown
    If e.Key = Key.Enter Then
        Dim SearchThread As New Thread(Sub() Search(Me.SearchBothBox.Text, 1))  <-- Exception occurs here when accessing SearcbhBothBox.Text
        SearchThread.Start()
    End If
End Sub

В любом случае, я собираюсь вытащить строку с помощью вызова.

    Dim SearchString As String
    Me.Dispatcher.Invoke(New Action(Sub() SearchString = Me.SearchBothBox.Text))

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


person MattB    schedule 11.08.2014    source источник
comment
Загляните в DispatcherTimer.   -  person patrick    schedule 11.08.2014
comment
Dim SearchThread As New Thread разве это не создаст новую тему? И доступ к текстовому полю в потоке этого является причиной того, что вы получаете исключение.   -  person PoweredByOrange    schedule 11.08.2014
comment
Зачем беспокоиться? Чтение TextBox перед запуском Thread намного проще. Также загляните в ThreadPool, Tasks и т. д. И как отображаются результаты?   -  person Henk Holterman    schedule 11.08.2014
comment
@HenkHolterman Я часто использую таксы, но в этом случае я просто использую поток для выбора строки в сетке данных - я бы предпочел не проверять, завершена ли она или вообще возвращаться к ней, поэтому я не стал не хочу использовать задачи.   -  person MattB    schedule 11.08.2014


Ответы (1)


Вот в этой строке:

Dim SearchThread As New Thread(Sub() Search(Me.SearchBothBox.Text, 1))

вы пытаетесь получить доступ к свойству элемента управления пользовательского интерфейса (TextBox.TextProperty) в потоке, отличном от потока пользовательского интерфейса. Отсюда и проблема.

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

person Rohit Vats    schedule 11.08.2014
comment
Ах, конечно. Сам должен был это заметить. Я всегда думаю, что подпрограмма работает в новом потоке, а не обязательно команда для запуска подпрограммы, работающей в новом потоке. Я должен иметь это в виду. Спасибо еще раз! - person MattB; 11.08.2014