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 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