ShowDialog from seperate thread
-
First, it sounds like you're abusing the BackgroundWorker. The BackgroundWorker is meant for running non-UI work on a background thread. If you want to update the UI during that work, call worker.ReportProgress, which will fire the ProgressChanged event on the UI thread. Also, the RunWorkerCompleted event will fire when the work is done, and it will fire on the UI thread. If you really have to create forms or controls on a background thread, you must ensure that the thread is STA. Look at Thread.SetApartmentState before you start the thread. You can't make BackgroundWorker threads be STA, so the BackgroundWorker won't work for this. Ideally, however, you use just a single thread to create and change your UI controls. Without this, you're going to have thread marshalling nightmares if different UIs need to be accessed on different threads. To sum up, use a background worker to perform non-UI related work on a background thread. If you need to update the UI from this background thread, call worker.ReportProgress and do the UI update inside a worker.ProgressChanged event handler.
Thanks for your response!! Ok, so I have moved my functionality to a thread instead of a background worker but I still get the error when I try to ShowDialog(Instance()) with-in my thread where the instance is the Main GUI. How do I invoke the whole form or Instance? By the way, I did set the SetApartmentState to STA. Lawrence.
-
Thanks for your response!! Ok, so I have moved my functionality to a thread instead of a background worker but I still get the error when I try to ShowDialog(Instance()) with-in my thread where the instance is the Main GUI. How do I invoke the whole form or Instance? By the way, I did set the SetApartmentState to STA. Lawrence.
What does Instance() do? It's hard to diagnose your problem without some source code. As I said before, I suspect you're approaching this wrong. Let's step back and ask, why do you want to create and show a form on a background thread?
-
What does Instance() do? It's hard to diagnose your problem without some source code. As I said before, I suspect you're approaching this wrong. Let's step back and ask, why do you want to create and show a form on a background thread?
Instance() returns static instance of the main form in my project.. Ok, I have a thread doing this work because I have a progress bar (marquee) on the main form that displays when potentially time consuming activities are happening. When I Show my new form it holds up the thread and I don’t see my progress bar being updated until after the form comes up. So I decided to kick off that work in its own thread so I can see my progress bar being updated. If you need anymore info please don’t hesitate to ask. Thanks, Lawrence
-
Instance() returns static instance of the main form in my project.. Ok, I have a thread doing this work because I have a progress bar (marquee) on the main form that displays when potentially time consuming activities are happening. When I Show my new form it holds up the thread and I don’t see my progress bar being updated until after the form comes up. So I decided to kick off that work in its own thread so I can see my progress bar being updated. If you need anymore info please don’t hesitate to ask. Thanks, Lawrence
I think the problem is that you're essentially modifying your main form on a background thread by making it become the owner of a form created on a different thread. This is bound to cause issues. I guess what I'm saying is, there may not be a way to assign one form to be the owner of another when they're created on different threads. I think that's "illegal" by Win32 UI standards. I could be wrong about that, but I've never seen it done. There are some alternatives that come to mind, both involve no threads:
- Forcibly update the main form's progress bar during the initialization of the second form. This involves sprinkling mainForm.ProgressBar.Update() calls during the creation and showing of the second form.
- Don't make the showing of the secondary form take so long: don't do any work during initialization, lazily initialize everything you can, wait for Application.Idle event to do anything, etc.
I guess both of those boil down to: find out what's taking long when showing the 2nd form, then spread out that work so it doesn't freeze your main form.
-
I think the problem is that you're essentially modifying your main form on a background thread by making it become the owner of a form created on a different thread. This is bound to cause issues. I guess what I'm saying is, there may not be a way to assign one form to be the owner of another when they're created on different threads. I think that's "illegal" by Win32 UI standards. I could be wrong about that, but I've never seen it done. There are some alternatives that come to mind, both involve no threads:
- Forcibly update the main form's progress bar during the initialization of the second form. This involves sprinkling mainForm.ProgressBar.Update() calls during the creation and showing of the second form.
- Don't make the showing of the secondary form take so long: don't do any work during initialization, lazily initialize everything you can, wait for Application.Idle event to do anything, etc.
I guess both of those boil down to: find out what's taking long when showing the 2nd form, then spread out that work so it doesn't freeze your main form.
-
I think the problem is that you're essentially modifying your main form on a background thread by making it become the owner of a form created on a different thread. This is bound to cause issues. I guess what I'm saying is, there may not be a way to assign one form to be the owner of another when they're created on different threads. I think that's "illegal" by Win32 UI standards. I could be wrong about that, but I've never seen it done. There are some alternatives that come to mind, both involve no threads:
- Forcibly update the main form's progress bar during the initialization of the second form. This involves sprinkling mainForm.ProgressBar.Update() calls during the creation and showing of the second form.
- Don't make the showing of the secondary form take so long: don't do any work during initialization, lazily initialize everything you can, wait for Application.Idle event to do anything, etc.
I guess both of those boil down to: find out what's taking long when showing the 2nd form, then spread out that work so it doesn't freeze your main form.
-
Tried option 1 and the Main Form will not render the progress bar while it’s trying to load form 2. After form 2 is loaded then I see the progress bar update. I am now back to square 1. Any other ideas? Lawrence
Lawrence, what is the 2nd form doing that causes the UI to freeze? Is it performing a lot of work? Does it have a lot of controls on it?
Tech, life, family, faith: Give me a visit. I'm currently blogging about: I'm Offended That You're Offended! The apostle Paul, modernly speaking: Epistles of Paul Judah Himango
-
Lawrence, what is the 2nd form doing that causes the UI to freeze? Is it performing a lot of work? Does it have a lot of controls on it?
Tech, life, family, faith: Give me a visit. I'm currently blogging about: I'm Offended That You're Offended! The apostle Paul, modernly speaking: Epistles of Paul Judah Himango
Judah, it doesn't have much controls but it's doing a webrequest POST which takes some time. I think I found a solution; the thread that starts the second form is being launched from a dummy class that inherits from Form. This allows the form to pop up; the only catch is I will have to do some manual work if I want to make it model. Lawrence
-
Judah, it doesn't have much controls but it's doing a webrequest POST which takes some time. I think I found a solution; the thread that starts the second form is being launched from a dummy class that inherits from Form. This allows the form to pop up; the only catch is I will have to do some manual work if I want to make it model. Lawrence
lgelliott wrote:
it's doing a webrequest POST
Can that be done on a background thread? This way, the UI won't freeze during the request. Anyways, whatever solution works for you, if subclassing works, well, hell, so be it. I'm feeling especially pragmatic today. :)
-
lgelliott wrote:
it's doing a webrequest POST
Can that be done on a background thread? This way, the UI won't freeze during the request. Anyways, whatever solution works for you, if subclassing works, well, hell, so be it. I'm feeling especially pragmatic today. :)