Application.DoEvents()

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Alan T

    Application.DoEvents()

    I tried to use a thread to process a iterative execution of processes but
    afraid my thread is not thread-safe.
    If I am not using a thread, my main form will become 'white' when switch
    forth and fro between other applications. So now I tried
    Application.DoE vents(). But it seems does not help, my main form still
    displays as 'white' when switch between other application.


  • Morten Wennevik

    #2
    Re: Application.DoE vents()

    Hi Alan,

    What Application.DoE vents is doing is halt the current processing and
    process pending events before continuing, but to make your form responsive
    you would need to call DoEvents several times per second. If you are
    unable to split your processing into small chunks that can be interrupted
    with a DoEvents, you will need to use another thread.


    On Thu, 12 Oct 2006 08:50:37 +0200, Alan T <alanpltseNOSPA M@yahoo.com.au>
    wrote:
    I tried to use a thread to process a iterative execution of processes but
    afraid my thread is not thread-safe.
    If I am not using a thread, my main form will become 'white' when switch
    forth and fro between other applications. So now I tried
    Application.DoE vents(). But it seems does not help, my main form still
    displays as 'white' when switch between other application.
    >
    >


    --
    Happy Coding!
    Morten Wennevik [C# MVP]

    Comment

    • Alan T

      #3
      Re: Application.DoE vents()

      So this is basically what I am doing:
      Press a button on main form, execute a loop, execute a third party
      application inside each loop.

      Click other applicaton on task bar and click my application, my main form is
      white now.

      "Morten Wennevik" <MortenWennevik @hotmail.comwro te in message
      news:op.thaq86d zklbvpo@tr024.b ouvet.no...
      Hi Alan,
      >
      What Application.DoE vents is doing is halt the current processing and
      process pending events before continuing, but to make your form responsive
      you would need to call DoEvents several times per second. If you are
      unable to split your processing into small chunks that can be interrupted
      with a DoEvents, you will need to use another thread.
      >
      >
      On Thu, 12 Oct 2006 08:50:37 +0200, Alan T <alanpltseNOSPA M@yahoo.com.au>
      wrote:
      >
      >I tried to use a thread to process a iterative execution of processes but
      >afraid my thread is not thread-safe.
      >If I am not using a thread, my main form will become 'white' when switch
      >forth and fro between other applications. So now I tried
      >Application.Do Events(). But it seems does not help, my main form still
      >displays as 'white' when switch between other application.
      >>
      >>
      >
      >
      >
      --
      Happy Coding!
      Morten Wennevik [C# MVP]

      Comment

      • Willy Denoyette [MVP]

        #4
        Re: Application.DoE vents()


        "Alan T" <alanpltseNOSPA M@yahoo.com.auw rote in message
        news:eRHoD7o7GH A.2384@TK2MSFTN GP04.phx.gbl...
        | So this is basically what I am doing:
        | Press a button on main form, execute a loop, execute a third party
        | application inside each loop.
        |

        What exactly do you mean here? you can't execute another application withing
        an application!
        Please post some code, or be more explicit.

        Willy.


        Comment

        • Alan T

          #5
          Re: Application.DoE vents()

          Sorry if my explanation was not clear:

          I got a main form, by pressing a button a looping process will be executed
          (while loop), for example 100 times.
          Inside this loop, I will execute a third-party application (eg. abc.exe).

          This is so far so good.

          However, if I click other application on the taskbar, for example, Windows
          Explorer, IE,... etc and then click my application, my main form will be
          blank.
          So what I think is I need to add Application.DoE vents() inside my while
          loop.

          After I added Application.DoE vents() in some places inside my click event
          handler and inside my while loop, it gave some improvements. But sometimes
          the response is still so slow and sometimes gave me blank screen on my main
          form.

          "Willy Denoyette [MVP]" <willy.denoyett e@telenet.bewro te in message
          news:eLopAZp7GH A.4568@TK2MSFTN GP02.phx.gbl...
          >
          "Alan T" <alanpltseNOSPA M@yahoo.com.auw rote in message
          news:eRHoD7o7GH A.2384@TK2MSFTN GP04.phx.gbl...
          | So this is basically what I am doing:
          | Press a button on main form, execute a loop, execute a third party
          | application inside each loop.
          |
          >
          What exactly do you mean here? you can't execute another application
          withing
          an application!
          Please post some code, or be more explicit.
          >
          Willy.
          >
          >

          Comment

          • Morten Wennevik

            #6
            Re: Application.DoE vents()

            I'm guessing it takes some time to fire up the other processes.

            In any case, for such simple tasks Threading shouldn't be too hard to
            learn.

            See Jon Skeet's article on multi-threading




            On Mon, 16 Oct 2006 02:19:27 +0200, Alan T <alanpltseNOSPA M@yahoo.com.au>
            wrote:
            Sorry if my explanation was not clear:
            >
            I got a main form, by pressing a button a looping process will be
            executed
            (while loop), for example 100 times.
            Inside this loop, I will execute a third-party application (eg. abc.exe).
            >
            This is so far so good.
            >
            However, if I click other application on the taskbar, for example,
            Windows
            Explorer, IE,... etc and then click my application, my main form will be
            blank.
            So what I think is I need to add Application.DoE vents() inside my while
            loop.
            >
            After I added Application.DoE vents() in some places inside my click event
            handler and inside my while loop, it gave some improvements. But
            sometimes
            the response is still so slow and sometimes gave me blank screen on my
            main
            form.
            >
            "Willy Denoyette [MVP]" <willy.denoyett e@telenet.bewro te in message
            news:eLopAZp7GH A.4568@TK2MSFTN GP02.phx.gbl...
            >>
            >"Alan T" <alanpltseNOSPA M@yahoo.com.auw rote in message
            >news:eRHoD7o7G HA.2384@TK2MSFT NGP04.phx.gbl.. .
            >| So this is basically what I am doing:
            >| Press a button on main form, execute a loop, execute a third party
            >| application inside each loop.
            >|
            >>
            >What exactly do you mean here? you can't execute another application
            >withing
            >an application!
            >Please post some code, or be more explicit.
            >>
            >Willy.
            >>
            >>
            >
            >


            --
            Happy Coding!
            Morten Wennevik [C# MVP]

            Comment

            • Willy Denoyette [MVP]

              #7
              Re: Application.DoE vents()

              Just to add to what Morten said, you should never ever execute something
              that takes more than a couple of 100 msec. (and even this might be
              disturbing) inside a UI handler. In your handler you are spawning an
              external application and you probably wait until this external process
              terminates (you better do so!), this will take longer than a few 100 msec,
              right?, well don't do this, handle this to an auxiliary thread, and you
              don't need this DoEvents any longer.

              Willy.




              "Alan T" <alanpltseNOSPA M@yahoo.com.auw rote in message
              news:OLM86iL8GH A.4348@TK2MSFTN GP03.phx.gbl...
              | Sorry if my explanation was not clear:
              |
              | I got a main form, by pressing a button a looping process will be executed
              | (while loop), for example 100 times.
              | Inside this loop, I will execute a third-party application (eg. abc.exe).
              |
              | This is so far so good.
              |
              | However, if I click other application on the taskbar, for example, Windows
              | Explorer, IE,... etc and then click my application, my main form will be
              | blank.
              | So what I think is I need to add Application.DoE vents() inside my while
              | loop.
              |
              | After I added Application.DoE vents() in some places inside my click event
              | handler and inside my while loop, it gave some improvements. But sometimes
              | the response is still so slow and sometimes gave me blank screen on my
              main
              | form.
              |
              | "Willy Denoyette [MVP]" <willy.denoyett e@telenet.bewro te in message
              | news:eLopAZp7GH A.4568@TK2MSFTN GP02.phx.gbl...
              | >
              | "Alan T" <alanpltseNOSPA M@yahoo.com.auw rote in message
              | news:eRHoD7o7GH A.2384@TK2MSFTN GP04.phx.gbl...
              | | So this is basically what I am doing:
              | | Press a button on main form, execute a loop, execute a third party
              | | application inside each loop.
              | |
              | >
              | What exactly do you mean here? you can't execute another application
              | withing
              | an application!
              | Please post some code, or be more explicit.
              | >
              | Willy.
              | >
              | >
              |
              |


              Comment

              • Alan T

                #8
                Re: Application.DoE vents()

                I tried a using thread and it solved my problem.
                But, how do I detect the thread is finished ?

                "Willy Denoyette [MVP]" <willy.denoyett e@telenet.bewro te in message
                news:%23HTRRTP8 GHA.3280@TK2MSF TNGP02.phx.gbl. ..
                Just to add to what Morten said, you should never ever execute something
                that takes more than a couple of 100 msec. (and even this might be
                disturbing) inside a UI handler. In your handler you are spawning an
                external application and you probably wait until this external process
                terminates (you better do so!), this will take longer than a few 100 msec,
                right?, well don't do this, handle this to an auxiliary thread, and you
                don't need this DoEvents any longer.
                >
                Willy.
                >
                >
                >
                >
                "Alan T" <alanpltseNOSPA M@yahoo.com.auw rote in message
                news:OLM86iL8GH A.4348@TK2MSFTN GP03.phx.gbl...
                | Sorry if my explanation was not clear:
                |
                | I got a main form, by pressing a button a looping process will be
                executed
                | (while loop), for example 100 times.
                | Inside this loop, I will execute a third-party application (eg.
                abc.exe).
                |
                | This is so far so good.
                |
                | However, if I click other application on the taskbar, for example,
                Windows
                | Explorer, IE,... etc and then click my application, my main form will be
                | blank.
                | So what I think is I need to add Application.DoE vents() inside my while
                | loop.
                |
                | After I added Application.DoE vents() in some places inside my click
                event
                | handler and inside my while loop, it gave some improvements. But
                sometimes
                | the response is still so slow and sometimes gave me blank screen on my
                main
                | form.
                |
                | "Willy Denoyette [MVP]" <willy.denoyett e@telenet.bewro te in message
                | news:eLopAZp7GH A.4568@TK2MSFTN GP02.phx.gbl...
                | >
                | "Alan T" <alanpltseNOSPA M@yahoo.com.auw rote in message
                | news:eRHoD7o7GH A.2384@TK2MSFTN GP04.phx.gbl...
                | | So this is basically what I am doing:
                | | Press a button on main form, execute a loop, execute a third party
                | | application inside each loop.
                | |
                | >
                | What exactly do you mean here? you can't execute another application
                | withing
                | an application!
                | Please post some code, or be more explicit.
                | >
                | Willy.
                | >
                | >
                |
                |
                >
                >

                Comment

                • Bruce Wood

                  #9
                  Re: Application.DoE vents()


                  Alan T wrote:
                  I tried a using thread and it solved my problem.
                  But, how do I detect the thread is finished ?
                  You don't actually "detect" that the thread is finished.

                  Instead, you have the method that runs in the background thread use
                  this.Invoke to make a call to another method, this time back in the UI
                  context, and in there do whatever you need to do now that the thread is
                  finished.

                  For example, I do some heavy processing when a user presses a button.

                  1. The button1_Clicked method that handles the button click disables
                  all of the controls on the form and then starts a new thread and has it
                  run DoHeavyProcessi ng.

                  2. At the end of DoHeavyProcessi ng, I do a this.Invoke() to run
                  DoneProcessing method on the UI thread.

                  3. DoneProcessing( ) then re-enables all of the controls on the form.

                  The final effect is that when the user presses the button, the form
                  changes so that he can't manipulate anything, but he can still minimize
                  it, maximize it, drag it around, etc. When the background process is
                  done the form's controls are re-enabled and the user can continue
                  working.

                  Comment

                  • Alan T

                    #10
                    Re: Application.DoE vents()

                    Can you elaborate about step (2) ?
                    How does the DoneProcessing on the UI thread be called by this.Invoke() ?

                    "Bruce Wood" <brucewood@cana da.comwrote in message
                    news:1161060289 .255878.217060@ f16g2000cwb.goo glegroups.com.. .
                    >
                    Alan T wrote:
                    >I tried a using thread and it solved my problem.
                    >But, how do I detect the thread is finished ?
                    >
                    You don't actually "detect" that the thread is finished.
                    >
                    Instead, you have the method that runs in the background thread use
                    this.Invoke to make a call to another method, this time back in the UI
                    context, and in there do whatever you need to do now that the thread is
                    finished.
                    >
                    For example, I do some heavy processing when a user presses a button.
                    >
                    1. The button1_Clicked method that handles the button click disables
                    all of the controls on the form and then starts a new thread and has it
                    run DoHeavyProcessi ng.
                    >
                    2. At the end of DoHeavyProcessi ng, I do a this.Invoke() to run
                    DoneProcessing method on the UI thread.
                    >
                    3. DoneProcessing( ) then re-enables all of the controls on the form.
                    >
                    The final effect is that when the user presses the button, the form
                    changes so that he can't manipulate anything, but he can still minimize
                    it, maximize it, drag it around, etc. When the background process is
                    done the form's controls are re-enabled and the user can continue
                    working.
                    >

                    Comment

                    • Morten Wennevik

                      #11
                      Re: Application.DoE vents()

                      Hi Alan

                      On Tue, 17 Oct 2006 07:39:07 +0200, Alan T <alanpltseNOSPA M@yahoo.com.au
                      wrote:
                      Can you elaborate about step (2) ?
                      How does the DoneProcessing on the UI thread be called by this.Invoke() ?

                      You create a Delegate and use the Delegate to notify the proper method
                      The code below will disable the controls on the form while
                      DoHeavyProcessi ng is doing some work (sleeping for five seconds)

                      public delegate void ProcessingDeleg ate();

                      private void button1_Click(o bject sender, EventArgs e)
                      {
                      foreach (Control c in this.Controls)
                      c.Enabled = false;

                      Thread t = new Thread(new ThreadStart(DoH eavyProcessing) );
                      t.Start();
                      }

                      private void DoneProcessing( )
                      {
                      foreach (Control c in this.Controls)
                      c.Enabled = true;
                      }

                      private void DoHeavyProcessi ng()
                      {
                      Thread.Sleep(50 00);

                      ProcessingDeleg ate d = new ProcessingDeleg ate(DoneProcess ing);

                      this.Invoke(d);
                      }


                      --
                      Happy Coding!
                      Morten Wennevik [C# MVP]

                      Comment

                      • Bruce Wood

                        #12
                        Re: Application.DoE vents()


                        Morten Wennevik wrote:
                        Hi Alan
                        >
                        On Tue, 17 Oct 2006 07:39:07 +0200, Alan T <alanpltseNOSPA M@yahoo.com.au>
                        wrote:
                        >
                        Can you elaborate about step (2) ?
                        How does the DoneProcessing on the UI thread be called by this.Invoke() ?
                        >
                        >
                        You create a Delegate and use the Delegate to notify the proper method
                        The code below will disable the controls on the form while
                        DoHeavyProcessi ng is doing some work (sleeping for five seconds)
                        >
                        public delegate void ProcessingDeleg ate();
                        >
                        private void button1_Click(o bject sender, EventArgs e)
                        {
                        foreach (Control c in this.Controls)
                        c.Enabled = false;
                        >
                        Thread t = new Thread(new ThreadStart(DoH eavyProcessing) );
                        t.Start();
                        }
                        >
                        private void DoneProcessing( )
                        {
                        foreach (Control c in this.Controls)
                        c.Enabled = true;
                        }
                        >
                        private void DoHeavyProcessi ng()
                        {
                        Thread.Sleep(50 00);
                        >
                        ProcessingDeleg ate d = new ProcessingDeleg ate(DoneProcess ing);
                        >
                        this.Invoke(d);
                        }
                        >
                        Hmm. ProcessingDeleg ate must be a .NET 2.0 thing. I do it like this in
                        ..NET 1.1 (but the effect is the same):

                        private void button1_Click(o bject sender, System.EventArg s e)
                        {
                        foreach (Control c in this.Controls) c.Enabled = false;
                        ThreadPool.Queu eUserWorkItem(n ew WaitCallback(Do HeavyProcessing ));
                        }

                        private void DoHeavyProcessi ng()
                        {
                        ... do whatever needs to be done ...
                        this.Invoke(new MethodInvoker(D oneProcessing)) ;
                        }

                        private void DoneProcessing( )
                        {
                        foreach (Control c in this.Controls) c.Enabled = true;
                        }

                        Comment

                        • Morten Wennevik

                          #13
                          Re: Application.DoE vents()

                          Hi Bruce,

                          There is no ProcessingDeleg ate in the framework, that is just a name for a
                          delegate, and delegates have been around since framework 1.1.

                          I was not aware of MethodInvoker, but after reading some documentations
                          (MSDN) I would not recommend using it. There is no listed overload for
                          Control.Invoke that takes MethodInvoker as parameter, which indicates that
                          this is not a supported feature. Furthermore, the documentations for
                          MethodInvoker states that it is an internal method and should not be used
                          in code. Nor does it support Compact Framework (which delegate does).


                          --
                          Happy Coding!
                          Morten Wennevik [C# MVP]

                          Comment

                          • Marc Gravell

                            #14
                            Re: Application.DoE vents()

                            It indicates no such thing!

                            Control.Invoke has two overloads; both accept a System.Delegate , with one
                            also accepting parameters. This means that *any* delegate (i.e. class
                            derived from System.Delegate ) can be used.

                            Note that System.Delegate is abstract, so by your logic *no* usage of
                            Control.Invoke is supported.

                            In short; MethodInvoker is just fine. All it means is "a delegate with void
                            return and no parameters". No more, no less. I can't see any "internal"
                            warning on MSDN... can you reference this?

                            As for "delegate" (note lower "d") being supported on the compact
                            framework... "delegate" is a keyword, not a type. Delegate is a type, but is
                            abstract. You need to talk in concrete terms here. The only reason
                            MethodInvoker isn't on CF is because it happens to be located in
                            Windows.Forms; however, logically it is identical to ThreadStart... which is
                            supported in CF1.0 and CF2.0.

                            So if you need "MethodInvo ker" usage on CF, either just use ThreadStart, or
                            (if this gets confusing to people) declare your own:

                            public delegate void MethodInvoker() ;

                            IMHO.

                            Marc


                            Comment

                            • Marc Gravell

                              #15
                              Re: Application.DoE vents()

                              Additional:

                              "Remarks" from MSDN2 (MSDN differs by a "don't" <="do not")
                              Represents a delegate that can execute any method in managed code that is declared void and takes no parameters.


                              <quote>MethodIn voker provides a simple delegate that is used to invoke a
                              method with a void parameter list. This delegate can be used when making
                              calls to a control's Invoke method, or when you need a simple delegate but
                              do not want to define one yourself.</quote>

                              Sounds fairly public (non-internal) to me... and it explicitely states that
                              it *is* suitable for use with "a control's Invoke method".

                              Marc


                              Comment

                              Working...