Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
CODE PROJECT For Those Who Code
  • Home
  • Articles
  • FAQ
Community
  1. Home
  2. General Programming
  3. C#
  4. ShowDialog from seperate thread

ShowDialog from seperate thread

Scheduled Pinned Locked Moved C#
questiontutorial
12 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • L Offline
    L Offline
    lgelliott
    wrote on last edited by
    #1

    All, I have a main GUI that is a singleton and I am trying to use it in a Background Worker that performs a ShowDialog on a newly created form. The ShowDialog needs and IWin32Window to properly render the new form, how do I "safely" use the main form instance in the ShowDialog? I keep getting [InvalidOperationException] and I am not sure how to use delegates on the entire form rather than a control. Thanks, Lawrence :confused:

    J 1 Reply Last reply
    0
    • L lgelliott

      All, I have a main GUI that is a singleton and I am trying to use it in a Background Worker that performs a ShowDialog on a newly created form. The ShowDialog needs and IWin32Window to properly render the new form, how do I "safely" use the main form instance in the ShowDialog? I keep getting [InvalidOperationException] and I am not sure how to use delegates on the entire form rather than a control. Thanks, Lawrence :confused:

      J Offline
      J Offline
      Judah Gabriel Himango
      wrote on last edited by
      #2

      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.

      L 1 Reply Last reply
      0
      • J Judah Gabriel Himango

        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.

        L Offline
        L Offline
        lgelliott
        wrote on last edited by
        #3

        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.

        J 1 Reply Last reply
        0
        • L lgelliott

          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.

          J Offline
          J Offline
          Judah Gabriel Himango
          wrote on last edited by
          #4

          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?

          L 1 Reply Last reply
          0
          • J Judah Gabriel Himango

            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?

            L Offline
            L Offline
            lgelliott
            wrote on last edited by
            #5

            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

            J 1 Reply Last reply
            0
            • L lgelliott

              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

              J Offline
              J Offline
              Judah Gabriel Himango
              wrote on last edited by
              #6

              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.

              L 2 Replies Last reply
              0
              • J Judah Gabriel Himango

                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.

                L Offline
                L Offline
                lgelliott
                wrote on last edited by
                #7

                Thanks for all your help. I will try to force the updates on to the main form from the second form because I can't lazy initialize this time. Thanks again. Lawrence

                1 Reply Last reply
                0
                • J Judah Gabriel Himango

                  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.

                  L Offline
                  L Offline
                  lgelliott
                  wrote on last edited by
                  #8

                  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

                  J 1 Reply Last reply
                  0
                  • L lgelliott

                    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

                    J Offline
                    J Offline
                    Judah Gabriel Himango
                    wrote on last edited by
                    #9

                    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

                    L 1 Reply Last reply
                    0
                    • J Judah Gabriel 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

                      L Offline
                      L Offline
                      lgelliott
                      wrote on last edited by
                      #10

                      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

                      J 1 Reply Last reply
                      0
                      • L lgelliott

                        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

                        J Offline
                        J Offline
                        Judah Gabriel Himango
                        wrote on last edited by
                        #11

                        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. :)

                        L 1 Reply Last reply
                        0
                        • J Judah Gabriel Himango

                          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. :)

                          L Offline
                          L Offline
                          lgelliott
                          wrote on last edited by
                          #12

                          It is being done in a background thread. I am not able to make the first form model because I am not doing a showdialog on the first form, I am doing it from my class that inherits form. So the model is really only on the thread. Lawrence

                          1 Reply Last reply
                          0
                          Reply
                          • Reply as topic
                          Log in to reply
                          • Oldest to Newest
                          • Newest to Oldest
                          • Most Votes


                          • Login

                          • Don't have an account? Register

                          • Login or register to search.
                          • First post
                            Last post
                          0
                          • Categories
                          • Recent
                          • Tags
                          • Popular
                          • World
                          • Users
                          • Groups