I'm new to WPF and vb.net programming and now I'm learning how backgroundworker works.
I'm building simple app to load image (to keep it simple, from a fixed path, like, "\\Server-01\d\ScanToLao31414.jpg") when user click a "Load Button". While Loading, the "Loading..." text appears.
The Background worker should do loading image in background thread. When it ready, it should return Bitmapimage to display on UI thread. The "Loading..." text shoul now gone.
The whole step should not freeze user interface.
The Error: Image1.Source = ThisIsImageReady ---> The calling thread cannot access this object because a different thread owns it.
Question: Are there anything to do with dispatcher on UI thread? I thought backgroundworker take care of that already?
(Part of )XAML:
<Window.Resources>
<cm:BackgroundWorker
x:Key="backgroundWorker"
WorkerReportsProgress="True"
WorkerSupportsCancellation="True"
DoWork="backgroundWorker_DoWork"
RunWorkerCompleted="backgroundWorker_RunWorkerCompleted">
</cm:BackgroundWorker>
</Window.Resources>
The Code:
Imports System.ComponentModel
Class Window1
Private backgroundWorker As BackgroundWorker
Public Sub New()
InitializeComponent()
backgroundWorker = CType(Me.FindResource("backgroundWorker"), BackgroundWorker)
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button1.Click
Button1.IsEnabled = False
Button2.IsEnabled = True
TextBlock1.Visibility = Windows.Visibility.Visible
backgroundWorker.RunWorkerAsync(New InputString("\\Server-01\d\ScanToLao31414.jpg"))
End Sub
Private Sub backgroundWorker_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)
Dim input As InputString = CType(e.Argument, InputString)
Dim ThisIsImage As BitmapImage = Loadimage.LoadNow(input.inString, backgroundWorker)
e.Result = ThisIsImage
End Sub
Private Sub backgroundWorker_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)
If Not e.Error Is Nothing Then
MessageBox.Show(e.Error.Message, "An Error Occurred")
Else
Dim ThisIsImageReady As BitmapImage = CType(e.Result, BitmapImage)
Image1.BeginInit()
Image1.Source = ThisIsImageReady
Image1.EndInit()
End If
Button1.IsEnabled = True
Button2.IsEnabled = False
TextBlock1.Visibility = Windows.Visibility.Hidden
End Sub
End Class
Public Class Loadimage
Public Shared Function LoadNow(ByVal loadstring As String, ByVal backgrounworker As BackgroundWorker) As BitmapImage
Dim bmp As New BitmapImage(New Uri(loadstring, UriKind.RelativeOrAbsolute))
bmp.CacheOption = BitmapCacheOption.OnLoad
LoadNow = bmp
Return LoadNow
End Function
End Class
Public Class InputString
Private _string As String
Public Property inString() As String
Get
Return _string
End Get
Set(ByVal value As String)
_string = value
End Set
End Property
Public Sub New(ByVal newInputString As String)
Me.inString = newInputString
End Sub
End Class