|
-
Feb 9th, 2010, 02:27 AM
#1
Thread Starter
New Member
[RESOLVED] VB.NET 08, WPF, Threads sharing Objects
Hi,
I#ve got a prolem whith threads sharing Objects. The exception is "The calling thread cannot access the object because a different thread owns it".
My plan is to have a background thread that loads an image. As soon as it's loaded, I want the UI-Thread the display it.
Code:
Imports System.Windows.Media.Imaging
Public Class test
Private m_Bitmap As BitmapImage
Public ReadOnly Property Bitmap() As BitmapImage
Get
Return m_Bitmap
End Get
End Property
Public Sub run()
m_Bitmap = New BitmapImage(New Uri("C:\Users\shess\Pictures\unbenannt1.png"))
End Sub
End Class
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button1.Click
Dim o As New test()
Dim t As New System.Threading.Thread(AddressOf o.run)
t.IsBackground = True
t.Start()
'o.run() 'THIS wors, bacause no second thread
t.Join()
Image1.Source = o.Bitmap 'THIS throws the error, because o.Bitmap was created in another thread
End Sub
Help is very much appreciated!
SP
-
Feb 9th, 2010, 07:30 PM
#2
Re: VB.NET 08, WPF, Threads sharing Objects
I haven't really worked with WPF so this is a bit of a guess. I read the documentation for the BitmapImage class and it says that it exists mainly to extend the BitmapSource class for use in XAML. As you're not using it in XAML, maybe try creating a BitmapSource instead and see if the same problem occurs. If it does then I would say that your only option would be to create the object on the UI thread if you intend to display it in the UI.
-
Feb 10th, 2010, 04:42 AM
#3
Thread Starter
New Member
Re: VB.NET 08, WPF, Threads sharing Objects
Thanks for you reply jmcilhinney,
as far as I'm aware BitmapSource is MustInherit hence I can't create an instance of it. Or didn't I understand you fully?
-
Feb 10th, 2010, 04:19 PM
#4
Re: VB.NET 08, WPF, Threads sharing Objects
You can definitely use a BitmapImage as I've used it in the past, like so:
vb Code:
Image1.Source = New BitmapImage(New Uri("C:\something.jpg"))
but I dont know how you would get around the fact that it will only let you use it on the thread that created it I'm afraid 
Oh and you are correct that you cant create an instance of BitmapSource as it is declared MustInherit
-
Feb 14th, 2010, 06:06 PM
#5
Hyperactive Member
Re: VB.NET 08, WPF, Threads sharing Objects
Why don't you use a different aproach and use a background worker, I've done it before using WPF.
You could use the completed event from the Backgroundworker and pass the image to the UI thread.
I'd like to get a response from you.
-
Feb 14th, 2010, 08:20 PM
#6
Re: VB.NET 08, WPF, Threads sharing Objects
 Originally Posted by Pac_741
Why don't you use a different aproach and use a background worker, I've done it before using WPF.
You could use the completed event from the Backgroundworker and pass the image to the UI thread.
I'd like to get a response from you.
The problem here is not the passing of data from one thread to another. The problem here is that the object cannot be used on a thread other than the one on which it was created. Using a BackgroundWorker won't change that. The DoWork event handler and the RunWorkerCompleted event handler are executed on different threads, so if you create the BitmapImage in the DoWork event handler and then try to use it in the RunWorkerCompleted event handler then you will encounter the same issue. Unlike a System.Drawing.Bitmap, which you would use in WinForms, it seems a System.Windows.Media.Imaging.BitmapImage is inherently associated with the thread on which it's created, much as a control is.
If the only option is to use a BitmapImage object then I'd say that the only option is to create it on the UI thread.
-
Feb 15th, 2010, 07:31 AM
#7
Thread Starter
New Member
Re: VB.NET 08, WPF, Threads sharing Objects
I tried the backgroundworker, but it's indeed the same error.
Creating and Loading the BitmapImage on the UI Thread is impossible. (Big picture up to 55MB across the network). That's why I currenty load a Winform Bitmap and convert it before using to BitmapImage. Unfortunately this convertion needs some (too much) time and needs to be done by the UI Thread.
Any better ideas?
-
Feb 15th, 2010, 12:15 PM
#8
Hyperactive Member
Re: VB.NET 08, WPF, Threads sharing Objects
Why don't you use WebRequest and download the image to a stream, and convert that to a byte array and pass it through the Completed event from the backgroundworker using e.result = img_byte_array.
Once you get the bytes in the completed event, try converting it to a bitmapimage.
It sounds good to me, what do you think ?
-
Feb 15th, 2010, 06:43 PM
#9
Re: VB.NET 08, WPF, Threads sharing Objects
I read something today about the fact that many WPF objects can't be used on a thread other than the thread on which they were created EXCEPT Freezable objects that have been frozen. I just had a look at the documentation for the BitmapImage class and it does indeed inherit Freezable. That would imply that you can create this BitmapImage object on a secondary thread, freeze it, then use it on the UI thread. Exactly what's involved in freezing an object I don't know, but I'm guessing that it's a single property or method involved. I'd say that you should be able to look that up yourself.
-
Feb 15th, 2010, 10:32 PM
#10
Hyperactive Member
Re: VB.NET 08, WPF, Threads sharing Objects
jmcilhinney, I've tried your suggestion but got no result.
I guess my approach is the best way to go on this scenario.
I don't have enough time to try it out, but I'm sure you could
do it by yourself.
-
Feb 16th, 2010, 02:46 AM
#11
Thread Starter
New Member
Re: VB.NET 08, WPF, Threads sharing Objects
Great! .freeze works! Thanks to all who were involved!
For other people finding this thread: acording to MSDN there is no way to unfreeze an object other then cloning it and using a copy..
vb Code:
Imports System.Windows.Media.Imaging Class Window1 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button1.Click Dim o As New test() Dim t As New System.Threading.Thread(AddressOf o.run) t.IsBackground = True t.Start() t.Join() Image1.Source = o.Bitmap 'THIS works now End Sub End Class Public Class test Private m_Bitmap As BitmapImage Public ReadOnly Property Bitmap() As BitmapImage Get Return m_Bitmap End Get End Property Public Sub run() m_Bitmap = New BitmapImage(New Uri("C:\Users\shess\Pictures\unbenannt1.png")) m_Bitmap.Freeze() 'THIS is the nub of the matter that makes it accessable by other threads. End Sub End Class
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|