|
-
Feb 27th, 2007, 10:29 AM
#1
[2005] Threading Cross Form
I have an app that does a bunch of stuff at startup before the main form is shown.
During this startup period, I don't show a splash screen, but there is a "wait please contacting server" form, which is just a form with a label and picturebox. The picturebox has an animated gif in it to show that the app is not frozen.
Now the issue I have is this:
I show and hide this form a number of times during this startup depending on how the startup process goes. For example, the first thing the app does is test for an internet connection, if it cant find one, it comes up with a form to tell them so, and displays any potential firewalls they have installed. However if the app finds an inet connection no problem, the firewall form is never shown, and it goes onto the next step of the startup routine (etc...)
What I need to be able to do, is make calls to show or hide this "wait" form at any given time. However while I don't care if the wait form is shown modally or not (because I set it to topmost, and any forms behind it are disabled while the wait form is showing), I do need it to be in its own thread, otherwise the animated gif doesn't animate. I assume this is due to the message looping somewhere.
So in the wait form I have a method called ShowMe() and it launches the wait form in its own thread, however I need to also have a HideMe() that will hide the form.
I guess what I am a bit stuck on, is how to make the cross thread calls. I have done cross thread calls before, but usually its when the seperate thread is doing some background work, and needs to update the UI, this is a bit different in that the main application thread is doing the background work, and the new thread should be showing this wait form.
So I need to figure out how to access the form on this seperate thread from my main thread, but from 2 different routines.
-
Feb 27th, 2007, 05:38 PM
#2
Re: [2005] Threading Cross Form
How is your ShowMe method implemented? Is it a Shared method?
-
Feb 27th, 2007, 05:46 PM
#3
Re: [2005] Threading Cross Form
Yes, its shared.
To be honest I tried so many implementations, I can't remember all of them.
But I was using a shared sub, and creating a single (private shared) instance of the wait form inside itself (basically like a default instance almost)
I actually have this working right now, but not without it throwing a threadabortexception. Currently if I simply catch the exception to supress it, it works, but obviously this is not the answer. So for now its in the code, and it works, but I have a HACK comment there with a note to fix it at some point
-
Feb 27th, 2007, 06:11 PM
#4
Re: [2005] Threading Cross Form
I would think that this should work but I haven't tested it:
Code:
Public Shared Sub HideMe()
If _instance.InvokeRequired Then
_instance.Invoke(New MethodInvoker(AddressOf _instance.Hide))
Else
_instance.Hide()
End If
End Sub
That assumes that '_instance' is a Shared variable that refers to the one and only instance of the class. You could create a similar CloseMe method that called the instance's Close method.
-
Feb 27th, 2007, 06:21 PM
#5
Re: [2005] Threading Cross Form
I tried that method but it didn't work.
I think the issue stemmed from the calls to show and hide and the concurrency of the thread.
When I log into work in a bit, I will post the code that I am currently using, so you can see if you notice what I can do to clear up the threadabortexception
-
Feb 27th, 2007, 06:47 PM
#6
Re: [2005] Threading Cross Form
If you're just calling Show on the form instance then I'm guessing that your thread probably terminates immediately. I've never used it anywhere but in a Main method but if you call Application.Run in your new thread instead of the Show method of the form then that will start a message loop and keep the thread running. When you call the form's Close method the call to Run will return and the thread will terminate.
-
Feb 27th, 2007, 07:11 PM
#7
Re: [2005] Threading Cross Form
I thought about that too, but I thought doing all that might be overkill and a waste of resources just to show a form with an animated GIF on it while the startup code is processing.
I suppose I could try it both ways and check memory and performance differences between the 2 methods.
-
Feb 27th, 2007, 07:20 PM
#8
Re: [2005] Threading Cross Form
I would suggest just using a splash screen. It's already shown on its own thread and you can access it via the My.Application.SplashScreen property. You know it's on a different thread so just use its Invoke method every time you want to affect it.
-
Feb 28th, 2007, 02:21 PM
#9
Re: [2005] Threading Cross Form
I will mess around with it and let you know.
I didn't think I could use the splashscreen because the "wait" form in question is actually housed in a DLL that the main app references. This is because this DLL is used in more than 1 app, that communicates with our server. So there is no application framework, etc.. in a DLL.
However I did notice via code I can set the splash screen property (since in the IDE dialog, you can only pick forms from the main app) so I will see if this might work how I need it to.
-
Feb 28th, 2007, 02:24 PM
#10
Re: [2005] Threading Cross Form
Oh yeah, now I remember why it won't work.
The wait form is called from both code in the DLL and code in the main exe GUI.
I can only access the application framework in the main exe, not in the dlls.
I suppose I could have my dll classes fire an event in order to alert the GUI for the need to display the wait form, but I think that is going a bit overboard, and would take some reworking of the code to add handlers and such for the event. That is more of a hack than what I am doing now I think
-
Mar 1st, 2007, 05:28 PM
#11
Re: [2005] Threading Cross Form
still haven't had any luck with this. I get what seems to be random threadabortexceptions when testing. Sometimes it works fine, sometimes it doesn't. The odd thing is I wrapped every place the form is even used in code with try/catch blocks, and it still throws an error all the way up to the highest level..
How can I go about securing this form on its own message loop. It may be more overhead, but the way it's working now isn't going to fly.
-
Mar 1st, 2007, 06:35 PM
#12
Re: [2005] Threading Cross Form
Like I said, I've never tried it but I think you call Application.Run(myForm) instead of myForm.Show(). You need to call it on the thread that owns the form though.
-
Mar 7th, 2007, 03:36 PM
#13
Re: [2005] Threading Cross Form
yeah again I thought of using application.run, but its the same thing as calling a .showdialog (aka it stops the current messageloop until the one you just created ends)
So far I have "technically" resolved this. I used a thread instance to create an instance of the wait form and call showdialog. When I call the close routine to close the wait form, it finds the window's handle (intptr) using the findwindow API, and then I use the SendMessage API and send a WM_CLOSE message to the handle of the form.
This causes the thread to stop, but not abort, which was causing all my previous problems. When the Show method is called again, I simply check the status of the thread, and if its stopped, I set it to nothing and create a new thread to show it again. Since the form is running in a different thread, its UI elements are not frozen. Also I don't know how well this would work for manipulating UI elements across threads, but this is simply a "splash" type form, so I am not accessing any UI elements on the form at all ever.
So far its working without any exceptions being thrown. I just need to test it for memory leaks.
I know its not very eligant, but hell it works. In the future I will try to design the classes to be able to run as background threads so I don't have to try to run the UI on 2 threads, I just didn't have the time for a full rewrite on this one.
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
|