none
Проблема с потоками VB.Net WPF RRS feed

  • Вопрос

  • Добрый вечер. Поясните, пожалуйста, где кроется собака. Есть две процедуры, которые выполняются отдельным потоком. Одна выставляет статическую картинку в Image, вторая анимированную с помощью WpfAnimatedGif.

        Public Sub SetImage(ByVal PathTo As String)
            Try
                Dim BitmapImage As New BitmapImage
                Using Bs = New IO.FileStream(PathTo, IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.Read)
                    BitmapImage.BeginInit()
                    BitmapImage.CacheOption = BitmapCacheOption.OnLoad
                    BitmapImage.StreamSource = Bs
                    BitmapImage.EndInit()
                End Using
                BitmapImage.Freeze()
    
                'Указываем максимальные размеры
                Dispatcher.Invoke(Sub()
                                      myImage.MaxWidth = BitmapImage.PixelWidth
                                      myImage.MaxHeight = BitmapImage.PixelHeight
                                      myImage.Source = BitmapImage
                                  End Sub)
            Catch ex As Exception
                Dispatcher.Invoke(Sub() loadDescr.Text = ex.Message)
            End Try
        End Sub
    
    
    
    
    
    
        Public Sub SetImageAnim(ByVal PathTo As String)
            Try
                Dim BitmapImage As New BitmapImage
                BitmapImage.BeginInit()
                BitmapImage.CacheOption = BitmapCacheOption.OnLoad
                BitmapImage.UriSource = New Uri(PathTo)
                BitmapImage.EndInit()
    
                'Указываем максимальные размеры
                Dispatcher.Invoke(Sub()
                                      myImage.MaxWidth = BitmapImage.PixelWidth
                                      myImage.MaxHeight = BitmapImage.PixelHeight
                                      WpfAnimatedGif.ImageBehavior.SetAnimatedSource(myImage, BitmapImage)
                                  End Sub)
    
            Catch ex As Exception
                Dispatcher.Invoke(Sub() loadDescr.Text = ex.Message)
            End Try
        End Sub

    Если вызвать первую процедуру в потоке, ошибок никаких нет. При вызове второй - внутри Dispatcher.Invoke получаем исключение "Вызывающий поток не может получить доступ к данному объекту, так как владельцем этого объекта является другой поток."

    Получается проблема в BitmapImage. Только не могу понять почему это происходит. В первом случае поток Bs закрывается и после этого BitmapImage обрабатывается нормально, а во втором случае BitmapImage как будто находится еще в каком-то другом потоке?



    • Изменено Siompc 17 марта 2021 г. 20:27
    17 марта 2021 г. 20:27

Ответы

  • Типично все операции с GUI объектами от создания до уничтожения должны производится на главном потоке, иначе возможны случайные подвисания UI. 

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

    Иногда объект можно сделать неизменяемым (Freeze), тогда появится ограниченная возможность с ним что то делать на других потоках.



    This posting is provided "AS IS" with no warranties, and confers no rights.

    • Помечено в качестве ответа Siompc 18 марта 2021 г. 10:38
    17 марта 2021 г. 22:22
    Модератор