JohnnyGr wrote:
> Well i dont really want to manage it... i just want to kill it, like
> no mercy kill it...
You should not do this. Your thread procedure should perform some loop
with a flag that can be step by other threads to indicate if the
procedure should stop. Then you should do a clean exit of the thread
procedure.
Your code is overly complicated. Here's a basic analysis:
>>> Private Sub lwFiles_ItemSelectionChanged(ByVal sender As Object,
>>> ByVal e
>>> As System.Windows.Forms.ListViewItemSelectionChangedEventArgs)
>>> Handles lwFiles.ItemSelectionChanged
This is a Forms event handler, so it runs on the GUI thread
>>> Dim CallBack As New AsyncCallback(AddressOf
>>> GetImageExifAndThumbnailCallBack)
>>> Dim ia As IAsyncResult = ad.BeginInvoke(e.Item.Tag,
>>> CallBack, ad)
Here you are using a ThreadPool thread to perform an async call. You
indicate that GetImageExifAndThumbnail is run on the ThreadPool threa,
and when it has finished the ThreadPool thread should call
GetImageExifAndThumbnailCallBack, to perform cleanup.
>>> Private Sub GetImageExifAndThumbnail(ByVal filename As String)
This is called on the ThreadPool thread and does the work.
>>> If CurrentImage = filename Then
>>> Dim uidel As New
>>> UpdateThumbnailAndExifDelegate(AddressOf UpdateThumbnailAndExif)
>>> uidel.Invoke(thumbnail, hash)
You're calling UpdateThumbnailAndExif on the current thread. (You've
called the delegate synchronously). What is the point?
>>> Private Sub UpdateThumbnailAndExif(ByRef thumbnail As Image,
>>> ByRef exifdata As Hashtable)
This is running on the ThreadPool thread.
>>> If Me.picPreview.InvokeRequired Then
>>> Dim d As New UpdateThumbnailAndExifDelegate(AddressOf
>>> UpdateThumbnailAndExif)
>>> Me.Invoke(d, New Object() {thumbnail, exifdata})
Now you intend to make some code run on the GUI thread. This should be
stuff that accesses the UI. But this cannot be right. You are creating a
delegate to *this* method and then invoking it on the GUI thread. What
is the point?
>>> Private Sub GetImageExifAndThumbnailCallBack(ByVal ia As
>>> IAsyncResult)
>>> Debug.WriteLine("callback")
>>> CType(ia.AsyncState, GetImageDataDelegate).EndInvoke(ia)
>>> End Sub
Finally this will cleanup the async result object.
You code seems to be a bit of a mess. You need to make sure that your
processing occurs on the ThreadPool thread and not on the GUI thread.
You have done that by making sure that GetImageExifAndThumbnail runs on
a ThreadPool thread by calling it asynchronously. Then you call
UpdateThumbnailAndExif synchronously on the ThreadPool thread (your use
of delegates here is pointless, you could have just called
UpdateThumbnailAndExif directly). You should not do this, you should
call it on the GUI thread. That way you can simplify
UpdateThumbnailAndExif so that it simply updates the image preview.
Now, you have to decide where the cancelling can occur. Presumably the
action that takes the most time is the call to GetThumbnailImage. If you
have a 'Cancel' button you could make the Click handler for this button
set a instance variable to true (it is normally false) then before the
call to GetThumbnailImage test the variable to see if it is true and if
so return.
GetThumbnailImage takes a delegate, of type
Image.GetThumbnailImageAbort. Presumably GetThumbnailImage will
periodically call this delegate to see if the operation should abort.
Unfortunately, the documentation says that this is not used in GDI+ 1.0.
Thus you should treat GetThumbnailImage as an atomic operation and you
either call it or you don't.
The alternative (implied in your question) is to terminate the thread.
You should never terminate a thread since it could screw up the state of
your object.
Richard
--
http://www.grimes.demon.co.uk/workshops/fusionWS.htm
http://www.grimes.demon.co.uk/workshops/securityWS.htm