Delegates and threads

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

    Delegates and threads

    I am having great difficulty understanding this and any code samples I find
    online are kilometres long and complicated to understand...Pl ease could
    someone give me a simple exampe of how to get a delegate passed to my worked
    class so that my main form can update its progress bar? I know it has
    something to do with begininvoke and endinvoke etc, but I just need a simple
    sample to understand the convention.


    Code from my main form:
    -----------------------------------
    form1Delegate dlgate = new form1Delegate(I ncreaseProgress Bar);
    //thing.countUpTo aMillionOrSomet hing(new
    form1Delegate(t his.IncreasePro gressBar));
    Thread thread = new Thread(new
    ThreadStart(thi ng.countUpToaMi llionOrSomethin g(dlgate)));
    thread.Start();
    -----------------------------------

    Code from my worker class called 'thing'
    -----------------------------------
    public static void countUpToaMilli onOrSomething(F orm1.form1Deleg ate
    myMethodDelegat e)
    {
    int x = 0;
    while ( x < 50)
    {
    Thread.Sleep(70 );
    x ++ ;
    myMethodDelegat e();
    }
    }
    -----------------------------------


    I can only get it to work synchronously with the following line:

    thing.countUpTo aMillionOrSomet hing(new
    form1Delegate(t his.IncreasePro gressBar));

    If I try compile with the thread example above it spews about 'Method name
    expected' and underlines the following bit of code:

    thing.countUpTo aMillionOrSomet hing(dlgate)

    Any help greatly appreciated,
    Thanks,
    Grant


  • Dave

    #2
    Re: Delegates and threads

    You don't need to use the Thread class to invoke the delegate asynchronously, however, invoking it using BeginInvoke will execute
    the method that the delegate points to on a ThreadPool thread. Also, ProgressBar (and any other WinForms control) requires most of
    its members to be executed/accessed on the thread that the control was created on. To account for this requirement, a proper
    example can't be too simple.

    Here's the simplest approach to updating a progress bar aynchronously in a WinForms app (the proper way). I'm assuming that each
    method is contained by a class derived from System.Windows. Forms.Form:

    private delegate void UpdateProgressI nvoker(int Position);
    private System.Windows. Forms.ProgressB ar progressBar;

    /// <summary>Test the progress bar asynchronous update code</summary>
    public void DoSomeWork()
    {
    progressBar.Min imum = 0;
    progressBar.Max imum = 100;

    for (int i = 0; i < 10000; i++)
    {
    // Create a pointer to the UpdateProgress method
    UpdateProgressI nvoker del = new UpdateProgressI nvoker(UpdatePr ogress);

    // Invoke the method asynchronously
    del.BeginInvoke ((int) (i / 100), null, null);

    // Tell the app to handle pending messages
    // (so the form doesn't freeze and the progress bar is updated visually)
    Application.DoE vents();
    }
    }


    /// <summary>
    /// This method does not update the progress bar directly. Instead, it ensures that the
    /// <see cref="UpdatePro gressCore" /> method (which actually does the work) is executed on the
    /// thread that the ProgressBar was created on.
    /// </summary>
    private void UpdateProgress( int Position)
    {
    // Check if the Form.InvokeRequ ired property is true. This will indicate that
    // the currently executing thread is not the thread that the ProgressBar was created on.
    // To update the progress bar synchronously, we will need to invoke the method on the
    // main thread.
    // [this] must be a reference to a Form object.
    if (!this.InvokeRe quired)
    {
    // Create a pointer to the UpdateProgressC ore method which performs the actual update
    UpdateProgressI nvoker del = new UpdateProgressI nvoker(UpdatePr ogressCore);

    // Invoke the method asynchronously on the main thread of the application.
    // By using Form.Invoke, we ensure that our progress bar will be updated properly.
    this.Invoke(del , new object[] { Position });
    }
    else
    // Currently executing thread is the ProgressBar's thread,
    // so update the progress bar normally
    UpdateProgressC ore(Position);
    }

    /// <summary>
    /// Do not call this method directly. Instead, call <see cref="UpdatePro gress" />.
    /// </summary>
    private void UpdateProgressC ore(int Position)
    {
    progressBar.Val ue = Position;
    }


    --
    Dave Sexton
    dave@www..jwaon line..com
    -----------------------------------------------------------------------
    "Grant" <gpsnett@hotmai l.com> wrote in message news:Oo0nRtaTFH A.3840@tk2msftn gp13.phx.gbl...[color=blue]
    >I am having great difficulty understanding this and any code samples I find online are kilometres long and complicated to
    >understand...P lease could someone give me a simple exampe of how to get a delegate passed to my worked class so that my main form
    >can update its progress bar? I know it has something to do with begininvoke and endinvoke etc, but I just need a simple sample to
    >understand the convention.
    >
    >
    > Code from my main form:
    > -----------------------------------
    > form1Delegate dlgate = new form1Delegate(I ncreaseProgress Bar);
    > //thing.countUpTo aMillionOrSomet hing(new form1Delegate(t his.IncreasePro gressBar));
    > Thread thread = new Thread(new ThreadStart(thi ng.countUpToaMi llionOrSomethin g(dlgate)));
    > thread.Start();
    > -----------------------------------
    >
    > Code from my worker class called 'thing'
    > -----------------------------------
    > public static void countUpToaMilli onOrSomething(F orm1.form1Deleg ate myMethodDelegat e)
    > {
    > int x = 0;
    > while ( x < 50)
    > {
    > Thread.Sleep(70 );
    > x ++ ;
    > myMethodDelegat e();
    > }
    > }
    > -----------------------------------
    >
    >
    > I can only get it to work synchronously with the following line:
    >
    > thing.countUpTo aMillionOrSomet hing(new form1Delegate(t his.IncreasePro gressBar));
    >
    > If I try compile with the thread example above it spews about 'Method name expected' and underlines the following bit of code:
    >
    > thing.countUpTo aMillionOrSomet hing(dlgate)
    >
    > Any help greatly appreciated,
    > Thanks,
    > Grant
    >
    >[/color]


    Comment

    • Richard Blewett [DevelopMentor]

      #3
      Re: Delegates and threads

      That looks great - apart from I don't understand why you call DoEvents - how does this help?

      Regards

      Richard Blewett - DevelopMentor



      nntp://news.microsoft. com/microsoft.publi c.dotnet.langua ges.csharp/<#mBN3FcTFHA.24 20@TK2MSFTNGP12 .phx.gbl>

      You don't need to use the Thread class to invoke the delegate asynchronously, however, invoking it using BeginInvoke will execute
      the method that the delegate points to on a ThreadPool thread. Also, ProgressBar (and any other WinForms control) requires most of
      its members to be executed/accessed on the thread that the control was created on. To account for this requirement, a proper
      example can't be too simple.

      Here's the simplest approach to updating a progress bar aynchronously in a WinForms app (the proper way). I'm assuming that each
      method is contained by a class derived from System.Windows. Forms.Form:

      private delegate void UpdateProgressI nvoker(int Position);
      private System.Windows. Forms.ProgressB ar progressBar;

      /// <summary>Test the progress bar asynchronous update code</summary>
      public void DoSomeWork()
      {
      progressBar.Min imum = 0;
      progressBar.Max imum = 100;

      for (int i = 0; i < 10000; i++)
      {
      // Create a pointer to the UpdateProgress method
      UpdateProgressI nvoker del = new UpdateProgressI nvoker(UpdatePr ogress);

      // Invoke the method asynchronously
      del.BeginInvoke ((int) (i / 100), null, null);

      // Tell the app to handle pending messages
      // (so the form doesn't freeze and the progress bar is updated visually)
      Application.DoE vents();
      }
      }


      /// <summary>
      /// This method does not update the progress bar directly. Instead, it ensures that the
      /// <see cref="UpdatePro gressCore" /> method (which actually does the work) is executed on the
      /// thread that the ProgressBar was created on.
      /// </summary>
      private void UpdateProgress( int Position)
      {
      // Check if the Form.InvokeRequ ired property is true. This will indicate that
      // the currently executing thread is not the thread that the ProgressBar was created on.
      // To update the progress bar synchronously, we will need to invoke the method on the
      // main thread.
      // [this] must be a reference to a Form object.
      if (!this.InvokeRe quired)
      {
      // Create a pointer to the UpdateProgressC ore method which performs the actual update
      UpdateProgressI nvoker del = new UpdateProgressI nvoker(UpdatePr ogressCore);

      // Invoke the method asynchronously on the main thread of the application.
      // By using Form.Invoke, we ensure that our progress bar will be updated properly.
      this.Invoke(del , new object[] { Position });
      }
      else
      // Currently executing thread is the ProgressBar's thread,
      // so update the progress bar normally
      UpdateProgressC ore(Position);
      }

      /// <summary>
      /// Do not call this method directly. Instead, call <see cref="UpdatePro gress" />.
      /// </summary>
      private void UpdateProgressC ore(int Position)
      {
      progressBar.Val ue = Position;
      }


      --
      Dave Sexton
      dave@www..jwaon line..com
      -----------------------------------------------------------------------
      "Grant" <gpsnett@hotmai l.com> wrote in message news:Oo0nRtaTFH A.3840@tk2msftn gp13.phx.gbl...[color=blue]
      >I am having great difficulty understanding this and any code samples I find online are kilometres long and complicated to
      >understand...P lease could someone give me a simple exampe of how to get a delegate passed to my worked class so that my main form
      >can update its progress bar? I know it has something to do with begininvoke and endinvoke etc, but I just need a simple sample to
      >understand the convention.
      >
      >
      > Code from my main form:
      > -----------------------------------
      > form1Delegate dlgate = new form1Delegate(I ncreaseProgress Bar);
      > //thing.countUpTo aMillionOrSomet hing(new form1Delegate(t his.IncreasePro gressBar));
      > Thread thread = new Thread(new ThreadStart(thi ng.countUpToaMi llionOrSomethin g(dlgate)));
      > thread.Start();
      > -----------------------------------
      >
      > Code from my worker class called 'thing'
      > -----------------------------------
      > public static void countUpToaMilli onOrSomething(F orm1.form1Deleg ate myMethodDelegat e)
      > {
      > int x = 0;
      > while ( x < 50)
      > {
      > Thread.Sleep(70 );
      > x ++ ;
      > myMethodDelegat e();
      > }
      > }
      > -----------------------------------
      >
      >
      > I can only get it to work synchronously with the following line:
      >
      > thing.countUpTo aMillionOrSomet hing(new form1Delegate(t his.IncreasePro gressBar));
      >
      > If I try compile with the thread example above it spews about 'Method name expected' and underlines the following bit of code:
      >
      > thing.countUpTo aMillionOrSomet hing(dlgate)
      >
      > Any help greatly appreciated,
      > Thanks,
      > Grant
      >
      >[/color]



      [microsoft.publi c.dotnet.langua ges.csharp]

      Comment

      • Dave

        #4
        Re: Delegates and threads

        Comment out Application.DoE vents and you'll see how it helps.

        Has to do with the fact that Windows uses a "Message Loop" so method invocations for WinForms controls aren't exactly "real-time".
        The message loop is like a queue, meaning first-in first-out. Your whole windows app depends on the messages from the queue
        reaching the main window procedure in order to process events, such as System.Windows. Forms.Form.Pain t event. Without this message,
        the form will never refresh, and neither will it's child controls (i.e. progress bar). User actions are also messages, so the
        window would "freeze" up, not allowing you to interact with it, while the "DoSomeWork " method is executing on the main window
        thread.

        In other words:
        1. Application.Run starts a message loop
        2. Your Form (main application window) processes messages on the loop
        3. My method (DoSomeWork) blocks the thread, not allowing it to accept messages while it is running
        4. Application.DoE vents allows the Form to process messages currently in the queue, effectively updating the Form while
        DoSomeWork is doing some work :)



        --
        Dave Sexton
        dave@www..jwaon line..com
        -----------------------------------------------------------------------
        "Richard Blewett [DevelopMentor]" <richardb@NOSPA Mdevelop.com> wrote in message news:uZys5gcTFH A.3952@TK2MSFTN GP15.phx.gbl...[color=blue]
        > That looks great - apart from I don't understand why you call DoEvents - how does this help?
        >
        > Regards
        >
        > Richard Blewett - DevelopMentor
        > http://www.dotnetconsult.co.uk/weblog
        >
        >
        > nntp://news.microsoft. com/microsoft.publi c.dotnet.langua ges.csharp/<#mBN3FcTFHA.24 20@TK2MSFTNGP12 .phx.gbl>
        >
        > You don't need to use the Thread class to invoke the delegate asynchronously, however, invoking it using BeginInvoke will execute
        > the method that the delegate points to on a ThreadPool thread. Also, ProgressBar (and any other WinForms control) requires most of
        > its members to be executed/accessed on the thread that the control was created on. To account for this requirement, a proper
        > example can't be too simple.
        >
        > Here's the simplest approach to updating a progress bar aynchronously in a WinForms app (the proper way). I'm assuming that each
        > method is contained by a class derived from System.Windows. Forms.Form:
        >
        > private delegate void UpdateProgressI nvoker(int Position);
        > private System.Windows. Forms.ProgressB ar progressBar;
        >
        > /// <summary>Test the progress bar asynchronous update code</summary>
        > public void DoSomeWork()
        > {
        > progressBar.Min imum = 0;
        > progressBar.Max imum = 100;
        >
        > for (int i = 0; i < 10000; i++)
        > {
        > // Create a pointer to the UpdateProgress method
        > UpdateProgressI nvoker del = new UpdateProgressI nvoker(UpdatePr ogress);
        >
        > // Invoke the method asynchronously
        > del.BeginInvoke ((int) (i / 100), null, null);
        >
        > // Tell the app to handle pending messages
        > // (so the form doesn't freeze and the progress bar is updated visually)
        > Application.DoE vents();
        > }
        > }
        >
        >
        > /// <summary>
        > /// This method does not update the progress bar directly. Instead, it ensures that the
        > /// <see cref="UpdatePro gressCore" /> method (which actually does the work) is executed on the
        > /// thread that the ProgressBar was created on.
        > /// </summary>
        > private void UpdateProgress( int Position)
        > {
        > // Check if the Form.InvokeRequ ired property is true. This will indicate that
        > // the currently executing thread is not the thread that the ProgressBar was created on.
        > // To update the progress bar synchronously, we will need to invoke the method on the
        > // main thread.
        > // [this] must be a reference to a Form object.
        > if (!this.InvokeRe quired)
        > {
        > // Create a pointer to the UpdateProgressC ore method which performs the actual update
        > UpdateProgressI nvoker del = new UpdateProgressI nvoker(UpdatePr ogressCore);
        >
        > // Invoke the method asynchronously on the main thread of the application.
        > // By using Form.Invoke, we ensure that our progress bar will be updated properly.
        > this.Invoke(del , new object[] { Position });
        > }
        > else
        > // Currently executing thread is the ProgressBar's thread,
        > // so update the progress bar normally
        > UpdateProgressC ore(Position);
        > }
        >
        > /// <summary>
        > /// Do not call this method directly. Instead, call <see cref="UpdatePro gress" />.
        > /// </summary>
        > private void UpdateProgressC ore(int Position)
        > {
        > progressBar.Val ue = Position;
        > }
        >
        >
        > --
        > Dave Sexton
        > dave@www..jwaon line..com
        > -----------------------------------------------------------------------
        > "Grant" <gpsnett@hotmai l.com> wrote in message news:Oo0nRtaTFH A.3840@tk2msftn gp13.phx.gbl...[color=green]
        > >I am having great difficulty understanding this and any code samples I find online are kilometres long and complicated to
        > >understand...P lease could someone give me a simple exampe of how to get a delegate passed to my worked class so that my main form
        > >can update its progress bar? I know it has something to do with begininvoke and endinvoke etc, but I just need a simple sample to
        > >understand the convention.
        > >
        > >
        > > Code from my main form:
        > > -----------------------------------
        > > form1Delegate dlgate = new form1Delegate(I ncreaseProgress Bar);
        > > //thing.countUpTo aMillionOrSomet hing(new form1Delegate(t his.IncreasePro gressBar));
        > > Thread thread = new Thread(new ThreadStart(thi ng.countUpToaMi llionOrSomethin g(dlgate)));
        > > thread.Start();
        > > -----------------------------------
        > >
        > > Code from my worker class called 'thing'
        > > -----------------------------------
        > > public static void countUpToaMilli onOrSomething(F orm1.form1Deleg ate myMethodDelegat e)
        > > {
        > > int x = 0;
        > > while ( x < 50)
        > > {
        > > Thread.Sleep(70 );
        > > x ++ ;
        > > myMethodDelegat e();
        > > }
        > > }
        > > -----------------------------------
        > >
        > >
        > > I can only get it to work synchronously with the following line:
        > >
        > > thing.countUpTo aMillionOrSomet hing(new form1Delegate(t his.IncreasePro gressBar));
        > >
        > > If I try compile with the thread example above it spews about 'Method name expected' and underlines the following bit of code:
        > >
        > > thing.countUpTo aMillionOrSomet hing(dlgate)
        > >
        > > Any help greatly appreciated,
        > > Thanks,
        > > Grant
        > >
        > >[/color]
        >
        >
        >
        > [microsoft.publi c.dotnet.langua ges.csharp][/color]


        Comment

        • Richard Blewett [DevelopMentor]

          #5
          Re: Delegates and threads

          Yes, I understand the internals of the windows messaging based windows subsystem. What was eluding me was the logic of the method. I had misread and thought you were calling DoSomeWork on a threadpool thread. In which case the Application.DoE vents succeeds but doesn't do what you expected.

          In any case your example shows something that seems bizarrre rather than what you would do. The UI thread is asking the worker thread to process a call which is marshalled back to the UI thread - its far simpler for the UI thread to update the progress bar directly and more effiecient.

          You example would be much more real world if the worker thread was performing the work and then passing the requests to update the progress bar back to the UI thread via control.Invoke (or BeginInvoke which is preferable in my book)

          Regards

          Richard Blewett - DevelopMentor



          Comment out Application.DoE vents and you'll see how it helps.

          Has to do with the fact that Windows uses a "Message Loop" so method invocations for WinForms controls aren't exactly "real-time".
          The message loop is like a queue, meaning first-in first-out. Your whole windows app depends on the messages from the queue
          reaching the main window procedure in order to process events, such as System.Windows. Forms.Form.Pain t event. Without this message,
          the form will never refresh, and neither will it's child controls (i.e. progress bar). User actions are also messages, so the
          window would "freeze" up, not allowing you to interact with it, while the "DoSomeWork " method is executing on the main window
          thread.

          In other words:
          1. Application.Run starts a message loop
          2. Your Form (main application window) processes messages on the loop
          3. My method (DoSomeWork) blocks the thread, not allowing it to accept messages while it is running
          4. Application.DoE vents allows the Form to process messages currently in the queue, effectively updating the Form while
          DoSomeWork is doing some work :)

          Comment

          • Willy Denoyette [MVP]

            #6
            Re: Delegates and threads

            Is there something particular you are trying to prove here?
            You run 'DoSomeWork' on the main UI thread, in 'DoSomeWork' you call an
            asynchronous delegate to run 'UpdateProgress ', as this one runs on a thread
            from the pool you have to marshal the call to 'UpdateProgress Core' (using
            the synchronous Invoke) so it runs on the UI thread.
            So basically, you are running a long task on the UI thread , call a delegate
            to update the UI on another thread and then need to Invoke to marshal the
            call to the UI is plain silly. No surprise you need to call DoEvents.
            Agreed, if you do not call DoEvents you'll consume all available pool
            threads and crash (Invoke doesn't return as the messages don't get
            dispatched) , but you shouldn't run the task on the UI thread in the first
            place.


            Willy.




            "Dave" <NOSPAM-dave@dotcomdata solutions.com> wrote in message
            news:%23wx5HucT FHA.616@TK2MSFT NGP12.phx.gbl.. .[color=blue]
            > Comment out Application.DoE vents and you'll see how it helps.
            >
            > Has to do with the fact that Windows uses a "Message Loop" so method
            > invocations for WinForms controls aren't exactly "real-time". The message
            > loop is like a queue, meaning first-in first-out. Your whole windows app
            > depends on the messages from the queue reaching the main window procedure
            > in order to process events, such as System.Windows. Forms.Form.Pain t event.
            > Without this message, the form will never refresh, and neither will it's
            > child controls (i.e. progress bar). User actions are also messages, so
            > the window would "freeze" up, not allowing you to interact with it, while
            > the "DoSomeWork " method is executing on the main window thread.
            >
            > In other words:
            > 1. Application.Run starts a message loop
            > 2. Your Form (main application window) processes messages on the loop
            > 3. My method (DoSomeWork) blocks the thread, not allowing it to accept
            > messages while it is running
            > 4. Application.DoE vents allows the Form to process messages currently
            > in the queue, effectively updating the Form while DoSomeWork is doing some
            > work :)
            >
            >
            >
            > --
            > Dave Sexton
            > dave@www..jwaon line..com
            > -----------------------------------------------------------------------
            > "Richard Blewett [DevelopMentor]" <richardb@NOSPA Mdevelop.com> wrote in
            > message news:uZys5gcTFH A.3952@TK2MSFTN GP15.phx.gbl...[color=green]
            >> That looks great - apart from I don't understand why you call DoEvents -
            >> how does this help?
            >>
            >> Regards
            >>
            >> Richard Blewett - DevelopMentor
            >> http://www.dotnetconsult.co.uk/weblog
            >>
            >>
            >>
            >> nntp://news.microsoft. com/microsoft.publi c.dotnet.langua ges.csharp/<#mBN3FcTFHA.24 20@TK2MSFTNGP12 .phx.gbl>
            >>
            >> You don't need to use the Thread class to invoke the delegate
            >> asynchronously, however, invoking it using BeginInvoke will execute
            >> the method that the delegate points to on a ThreadPool thread. Also,
            >> ProgressBar (and any other WinForms control) requires most of
            >> its members to be executed/accessed on the thread that the control was
            >> created on. To account for this requirement, a proper
            >> example can't be too simple.
            >>
            >> Here's the simplest approach to updating a progress bar aynchronously in
            >> a WinForms app (the proper way). I'm assuming that each
            >> method is contained by a class derived from System.Windows. Forms.Form:
            >>
            >> private delegate void UpdateProgressI nvoker(int Position);
            >> private System.Windows. Forms.ProgressB ar progressBar;
            >>
            >> /// <summary>Test the progress bar asynchronous update code</summary>
            >> public void DoSomeWork()
            >> {
            >> progressBar.Min imum = 0;
            >> progressBar.Max imum = 100;
            >>
            >> for (int i = 0; i < 10000; i++)
            >> {
            >> // Create a pointer to the UpdateProgress method
            >> UpdateProgressI nvoker del = new UpdateProgressI nvoker(UpdatePr ogress);
            >>
            >> // Invoke the method asynchronously
            >> del.BeginInvoke ((int) (i / 100), null, null);
            >>
            >> // Tell the app to handle pending messages
            >> // (so the form doesn't freeze and the progress bar is updated visually)
            >> Application.DoE vents();
            >> }
            >> }
            >>
            >>
            >> /// <summary>
            >> /// This method does not update the progress bar directly. Instead, it
            >> ensures that the
            >> /// <see cref="UpdatePro gressCore" /> method (which actually does the
            >> work) is executed on the
            >> /// thread that the ProgressBar was created on.
            >> /// </summary>
            >> private void UpdateProgress( int Position)
            >> {
            >> // Check if the Form.InvokeRequ ired property is true. This will indicate
            >> that
            >> // the currently executing thread is not the thread that the ProgressBar
            >> was created on.
            >> // To update the progress bar synchronously, we will need to invoke the
            >> method on the
            >> // main thread.
            >> // [this] must be a reference to a Form object.
            >> if (!this.InvokeRe quired)
            >> {
            >> // Create a pointer to the UpdateProgressC ore method which performs the
            >> actual update
            >> UpdateProgressI nvoker del = new
            >> UpdateProgressI nvoker(UpdatePr ogressCore);
            >>
            >> // Invoke the method asynchronously on the main thread of the
            >> application.
            >> // By using Form.Invoke, we ensure that our progress bar will be updated
            >> properly.
            >> this.Invoke(del , new object[] { Position });
            >> }
            >> else
            >> // Currently executing thread is the ProgressBar's thread,
            >> // so update the progress bar normally
            >> UpdateProgressC ore(Position);
            >> }
            >>
            >> /// <summary>
            >> /// Do not call this method directly. Instead, call <see
            >> cref="UpdatePro gress" />.
            >> /// </summary>
            >> private void UpdateProgressC ore(int Position)
            >> {
            >> progressBar.Val ue = Position;
            >> }
            >>
            >>
            >> --
            >> Dave Sexton
            >> dave@www..jwaon line..com
            >> -----------------------------------------------------------------------
            >> "Grant" <gpsnett@hotmai l.com> wrote in message
            >> news:Oo0nRtaTFH A.3840@tk2msftn gp13.phx.gbl...[color=darkred]
            >> >I am having great difficulty understanding this and any code samples I
            >> >find online are kilometres long and complicated to
            >> >understand...P lease could someone give me a simple exampe of how to get
            >> >a delegate passed to my worked class so that my main form
            >> >can update its progress bar? I know it has something to do with
            >> >begininvoke and endinvoke etc, but I just need a simple sample to
            >> >understand the convention.
            >> >
            >> >
            >> > Code from my main form:
            >> > -----------------------------------
            >> > form1Delegate dlgate = new form1Delegate(I ncreaseProgress Bar);
            >> > //thing.countUpTo aMillionOrSomet hing(new
            >> > form1Delegate(t his.IncreasePro gressBar));
            >> > Thread thread = new Thread(new
            >> > ThreadStart(thi ng.countUpToaMi llionOrSomethin g(dlgate)));
            >> > thread.Start();
            >> > -----------------------------------
            >> >
            >> > Code from my worker class called 'thing'
            >> > -----------------------------------
            >> > public static void countUpToaMilli onOrSomething(F orm1.form1Deleg ate
            >> > myMethodDelegat e)
            >> > {
            >> > int x = 0;
            >> > while ( x < 50)
            >> > {
            >> > Thread.Sleep(70 );
            >> > x ++ ;
            >> > myMethodDelegat e();
            >> > }
            >> > }
            >> > -----------------------------------
            >> >
            >> >
            >> > I can only get it to work synchronously with the following line:
            >> >
            >> > thing.countUpTo aMillionOrSomet hing(new
            >> > form1Delegate(t his.IncreasePro gressBar));
            >> >
            >> > If I try compile with the thread example above it spews about 'Method
            >> > name expected' and underlines the following bit of code:
            >> >
            >> > thing.countUpTo aMillionOrSomet hing(dlgate)
            >> >
            >> > Any help greatly appreciated,
            >> > Thanks,
            >> > Grant
            >> >
            >> >[/color]
            >>
            >>
            >>
            >> [microsoft.publi c.dotnet.langua ges.csharp][/color]
            >
            >[/color]


            Comment

            • Dave

              #7
              Re: Delegates and threads

              Lol. Thanks for the feedback, but does anyone read the initial question anymore??
              [color=blue]
              > Please could someone give me a simple exampe of how to get a delegate passed to my worked class so that my main form can update
              > its progress bar?[/color]

              That's what he wanted. He needed to understand delegates, I assumed.

              Anyway... I think you missed the part where i check Form.RequiresIn voke, and if it is false, do the update directly.
              UpdateProgessCo re is exactly what is sounds like... a method to update a progress bar. How do I know he's able to do this in one
              line of code? That's why it's a seperate method.

              Encapsulation.

              --
              Dave Sexton
              dave@www..jwaon line..com
              -----------------------------------------------------------------------
              "Willy Denoyette [MVP]" <willy.denoyett e@telenet.be> wrote in message news:eK1S$HdTFH A.3140@TK2MSFTN GP14.phx.gbl...[color=blue]
              > Is there something particular you are trying to prove here?
              > You run 'DoSomeWork' on the main UI thread, in 'DoSomeWork' you call an asynchronous delegate to run 'UpdateProgress ', as this one
              > runs on a thread from the pool you have to marshal the call to 'UpdateProgress Core' (using the synchronous Invoke) so it runs on
              > the UI thread.
              > So basically, you are running a long task on the UI thread , call a delegate to update the UI on another thread and then need to
              > Invoke to marshal the call to the UI is plain silly. No surprise you need to call DoEvents.
              > Agreed, if you do not call DoEvents you'll consume all available pool threads and crash (Invoke doesn't return as the messages
              > don't get dispatched) , but you shouldn't run the task on the UI thread in the first place.
              >
              >
              > Willy.
              >
              >
              >
              >
              > "Dave" <NOSPAM-dave@dotcomdata solutions.com> wrote in message news:%23wx5HucT FHA.616@TK2MSFT NGP12.phx.gbl.. .[color=green]
              >> Comment out Application.DoE vents and you'll see how it helps.
              >>
              >> Has to do with the fact that Windows uses a "Message Loop" so method invocations for WinForms controls aren't exactly
              >> "real-time". The message loop is like a queue, meaning first-in first-out. Your whole windows app depends on the messages from
              >> the queue reaching the main window procedure in order to process events, such as System.Windows. Forms.Form.Pain t event. Without
              >> this message, the form will never refresh, and neither will it's child controls (i.e. progress bar). User actions are also
              >> messages, so the window would "freeze" up, not allowing you to interact with it, while the "DoSomeWork " method is executing on
              >> the main window thread.
              >>
              >> In other words:
              >> 1. Application.Run starts a message loop
              >> 2. Your Form (main application window) processes messages on the loop
              >> 3. My method (DoSomeWork) blocks the thread, not allowing it to accept messages while it is running
              >> 4. Application.DoE vents allows the Form to process messages currently in the queue, effectively updating the Form while
              >> DoSomeWork is doing some work :)
              >>
              >>
              >>
              >> --
              >> Dave Sexton
              >> dave@www..jwaon line..com
              >> -----------------------------------------------------------------------
              >> "Richard Blewett [DevelopMentor]" <richardb@NOSPA Mdevelop.com> wrote in message news:uZys5gcTFH A.3952@TK2MSFTN GP15.phx.gbl...[color=darkred]
              >>> That looks great - apart from I don't understand why you call DoEvents - how does this help?
              >>>
              >>> Regards
              >>>
              >>> Richard Blewett - DevelopMentor
              >>> http://www.dotnetconsult.co.uk/weblog
              >>>
              >>>
              >>>
              >>> nntp://news.microsoft. com/microsoft.publi c.dotnet.langua ges.csharp/<#mBN3FcTFHA.24 20@TK2MSFTNGP12 .phx.gbl>
              >>>
              >>> You don't need to use the Thread class to invoke the delegate asynchronously, however, invoking it using BeginInvoke will
              >>> execute
              >>> the method that the delegate points to on a ThreadPool thread. Also, ProgressBar (and any other WinForms control) requires most
              >>> of
              >>> its members to be executed/accessed on the thread that the control was created on. To account for this requirement, a proper
              >>> example can't be too simple.
              >>>
              >>> Here's the simplest approach to updating a progress bar aynchronously in a WinForms app (the proper way). I'm assuming that each
              >>> method is contained by a class derived from System.Windows. Forms.Form:
              >>>
              >>> private delegate void UpdateProgressI nvoker(int Position);
              >>> private System.Windows. Forms.ProgressB ar progressBar;
              >>>
              >>> /// <summary>Test the progress bar asynchronous update code</summary>
              >>> public void DoSomeWork()
              >>> {
              >>> progressBar.Min imum = 0;
              >>> progressBar.Max imum = 100;
              >>>
              >>> for (int i = 0; i < 10000; i++)
              >>> {
              >>> // Create a pointer to the UpdateProgress method
              >>> UpdateProgressI nvoker del = new UpdateProgressI nvoker(UpdatePr ogress);
              >>>
              >>> // Invoke the method asynchronously
              >>> del.BeginInvoke ((int) (i / 100), null, null);
              >>>
              >>> // Tell the app to handle pending messages
              >>> // (so the form doesn't freeze and the progress bar is updated visually)
              >>> Application.DoE vents();
              >>> }
              >>> }
              >>>
              >>>
              >>> /// <summary>
              >>> /// This method does not update the progress bar directly. Instead, it ensures that the
              >>> /// <see cref="UpdatePro gressCore" /> method (which actually does the work) is executed on the
              >>> /// thread that the ProgressBar was created on.
              >>> /// </summary>
              >>> private void UpdateProgress( int Position)
              >>> {
              >>> // Check if the Form.InvokeRequ ired property is true. This will indicate that
              >>> // the currently executing thread is not the thread that the ProgressBar was created on.
              >>> // To update the progress bar synchronously, we will need to invoke the method on the
              >>> // main thread.
              >>> // [this] must be a reference to a Form object.
              >>> if (!this.InvokeRe quired)
              >>> {
              >>> // Create a pointer to the UpdateProgressC ore method which performs the actual update
              >>> UpdateProgressI nvoker del = new UpdateProgressI nvoker(UpdatePr ogressCore);
              >>>
              >>> // Invoke the method asynchronously on the main thread of the application.
              >>> // By using Form.Invoke, we ensure that our progress bar will be updated properly.
              >>> this.Invoke(del , new object[] { Position });
              >>> }
              >>> else
              >>> // Currently executing thread is the ProgressBar's thread,
              >>> // so update the progress bar normally
              >>> UpdateProgressC ore(Position);
              >>> }
              >>>
              >>> /// <summary>
              >>> /// Do not call this method directly. Instead, call <see cref="UpdatePro gress" />.
              >>> /// </summary>
              >>> private void UpdateProgressC ore(int Position)
              >>> {
              >>> progressBar.Val ue = Position;
              >>> }
              >>>
              >>>
              >>> --
              >>> Dave Sexton
              >>> dave@www..jwaon line..com
              >>> -----------------------------------------------------------------------
              >>> "Grant" <gpsnett@hotmai l.com> wrote in message news:Oo0nRtaTFH A.3840@tk2msftn gp13.phx.gbl...
              >>> >I am having great difficulty understanding this and any code samples I find online are kilometres long and complicated to
              >>> >understand...P lease could someone give me a simple exampe of how to get a delegate passed to my worked class so that my main
              >>> >form
              >>> >can update its progress bar? I know it has something to do with begininvoke and endinvoke etc, but I just need a simple sample
              >>> >to
              >>> >understand the convention.
              >>> >
              >>> >
              >>> > Code from my main form:
              >>> > -----------------------------------
              >>> > form1Delegate dlgate = new form1Delegate(I ncreaseProgress Bar);
              >>> > //thing.countUpTo aMillionOrSomet hing(new form1Delegate(t his.IncreasePro gressBar));
              >>> > Thread thread = new Thread(new ThreadStart(thi ng.countUpToaMi llionOrSomethin g(dlgate)));
              >>> > thread.Start();
              >>> > -----------------------------------
              >>> >
              >>> > Code from my worker class called 'thing'
              >>> > -----------------------------------
              >>> > public static void countUpToaMilli onOrSomething(F orm1.form1Deleg ate myMethodDelegat e)
              >>> > {
              >>> > int x = 0;
              >>> > while ( x < 50)
              >>> > {
              >>> > Thread.Sleep(70 );
              >>> > x ++ ;
              >>> > myMethodDelegat e();
              >>> > }
              >>> > }
              >>> > -----------------------------------
              >>> >
              >>> >
              >>> > I can only get it to work synchronously with the following line:
              >>> >
              >>> > thing.countUpTo aMillionOrSomet hing(new form1Delegate(t his.IncreasePro gressBar));
              >>> >
              >>> > If I try compile with the thread example above it spews about 'Method name expected' and underlines the following bit of code:
              >>> >
              >>> > thing.countUpTo aMillionOrSomet hing(dlgate)
              >>> >
              >>> > Any help greatly appreciated,
              >>> > Thanks,
              >>> > Grant
              >>> >
              >>> >
              >>>
              >>>
              >>>
              >>> [microsoft.publi c.dotnet.langua ges.csharp][/color]
              >>
              >>[/color]
              >
              >[/color]


              Comment

              • Willy Denoyette [MVP]

                #8
                Re: Delegates and threads

                Inline

                Willy.

                "Dave" <NOSPAM-dave@dotcomdata solutions.com> wrote in message
                news:OuTvKffTFH A.2872@TK2MSFTN GP14.phx.gbl...[color=blue]
                > Lol. Thanks for the feedback, but does anyone read the initial question
                > anymore??
                >[/color]

                Sure I do, but as OP started with: "I am having great difficulty
                understanding this and any code samples I find .." ... does ring a bell for
                me. Clearly OP doesn't understand delegates, and he thinks he needs a
                delegate to update the UI, which is the wrong assumption if you take a look
                at his code sample .

                In his sample he runs 'countUpToaMill ionOrSomething' on a spawned background
                thread, while you do the actual work on the UI thread - something you
                shouldn't do (unless it takes less than lets say a second) if you need to
                keep the UI responsive, right?. More, you have to call DoEvents() to keep
                the UI responsive, I guess you know where DoEvents comes from and where it
                belongs, do you?

                [color=blue][color=green]
                >> Please could someone give me a simple exampe of how to get a delegate
                >> passed to my worked class so that my main form can update its progress
                >> bar?[/color]
                >
                > That's what he wanted. He needed to understand delegates, I assumed.
                >[/color]

                Strictly spoken, yes, but IMO OP's 'hidden real' question was "How to update
                the UI" from a worker thread, while you showed how to use a delegate. I
                could be wrong but, I'm affraid OP is getting even more confused when
                looking at your code.
                [color=blue]
                > Anyway... I think you missed the part where i check Form.RequiresIn voke,
                > and if it is false, do the update directly.[/color]

                Yes, but in this particular sample it's always true because its called from
                a threadpool thread.
                [color=blue]
                > UpdateProgessCo re is exactly what is sounds like... a method to update a
                > progress bar. How do I know he's able to do this in one line of code?
                > That's why it's a seperate method.
                >
                > Encapsulation.
                >
                > --
                > Dave Sexton
                > dave@www..jwaon line..com[/color]


                Comment

                • Grant

                  #9
                  Re: Delegates and threads

                  Yes thats right I need to understand how to pass a delegate to a new thread
                  I have created. I can do it synchronously but not asynchronously. So in the
                  example provided the 'BeginInvoke' command executes that on a seperate
                  thread using the threadpool, however Richard says:
                  ------
                  You example would be much more real world if the worker thread was
                  performing the work and then passing the requests to update the progress bar
                  back to the UI thread via control.Invoke (or BeginInvoke which is preferable
                  in my book)
                  ------

                  That is really what I was after. I have a sepereate static class that does
                  all the work. I need this class to receive the delegate but I dont know how
                  to send it there on the thread I created, which Id like to manage myself and
                  not have it automatically done (I heard DoEvents was evil in VB6, is it the
                  same for .NET?) . Im starting up my own single thread and not using the
                  "threadpool waitcallback" way of creating threads (havent learnt how to to
                  do those just yet). So why does the IDE tell me "Method name
                  expected" when I get to the following line of code:
                  thing.countUpTo aMillionOrSomet hing(dlgate). What method name is it
                  expecting? I have created the delegate (which I understand is a wrapper and
                  points to the progress bar updater function I created on the main form).

                  Thanks for all your help,
                  Cheers,
                  Grant


                  "Dave" <NOSPAM-dave@dotcomdata solutions.com> wrote in message
                  news:OuTvKffTFH A.2872@TK2MSFTN GP14.phx.gbl...[color=blue]
                  > Lol. Thanks for the feedback, but does anyone read the initial question
                  > anymore??
                  >[color=green]
                  >> Please could someone give me a simple exampe of how to get a delegate
                  >> passed to my worked class so that my main form can update its progress
                  >> bar?[/color]
                  >
                  > That's what he wanted. He needed to understand delegates, I assumed.
                  >
                  > Anyway... I think you missed the part where i check Form.RequiresIn voke,
                  > and if it is false, do the update directly.
                  > UpdateProgessCo re is exactly what is sounds like... a method to update a
                  > progress bar. How do I know he's able to do this in one line of code?
                  > That's why it's a seperate method.
                  >
                  > Encapsulation.
                  >
                  > --
                  > Dave Sexton
                  > dave@www..jwaon line..com
                  > -----------------------------------------------------------------------
                  > "Willy Denoyette [MVP]" <willy.denoyett e@telenet.be> wrote in message
                  > news:eK1S$HdTFH A.3140@TK2MSFTN GP14.phx.gbl...[color=green]
                  >> Is there something particular you are trying to prove here?
                  >> You run 'DoSomeWork' on the main UI thread, in 'DoSomeWork' you call an
                  >> asynchronous delegate to run 'UpdateProgress ', as this one runs on a
                  >> thread from the pool you have to marshal the call to 'UpdateProgress Core'
                  >> (using the synchronous Invoke) so it runs on the UI thread.
                  >> So basically, you are running a long task on the UI thread , call a
                  >> delegate to update the UI on another thread and then need to Invoke to
                  >> marshal the call to the UI is plain silly. No surprise you need to call
                  >> DoEvents.
                  >> Agreed, if you do not call DoEvents you'll consume all available pool
                  >> threads and crash (Invoke doesn't return as the messages don't get
                  >> dispatched) , but you shouldn't run the task on the UI thread in the
                  >> first place.
                  >>
                  >>
                  >> Willy.
                  >>
                  >>
                  >>
                  >>
                  >> "Dave" <NOSPAM-dave@dotcomdata solutions.com> wrote in message
                  >> news:%23wx5HucT FHA.616@TK2MSFT NGP12.phx.gbl.. .[color=darkred]
                  >>> Comment out Application.DoE vents and you'll see how it helps.
                  >>>
                  >>> Has to do with the fact that Windows uses a "Message Loop" so method
                  >>> invocations for WinForms controls aren't exactly "real-time". The
                  >>> message loop is like a queue, meaning first-in first-out. Your whole
                  >>> windows app depends on the messages from the queue reaching the main
                  >>> window procedure in order to process events, such as
                  >>> System.Windows. Forms.Form.Pain t event. Without this message, the form
                  >>> will never refresh, and neither will it's child controls (i.e. progress
                  >>> bar). User actions are also messages, so the window would "freeze" up,
                  >>> not allowing you to interact with it, while the "DoSomeWork " method is
                  >>> executing on the main window thread.
                  >>>
                  >>> In other words:
                  >>> 1. Application.Run starts a message loop
                  >>> 2. Your Form (main application window) processes messages on the loop
                  >>> 3. My method (DoSomeWork) blocks the thread, not allowing it to
                  >>> accept messages while it is running
                  >>> 4. Application.DoE vents allows the Form to process messages currently
                  >>> in the queue, effectively updating the Form while DoSomeWork is doing
                  >>> some work :)
                  >>>
                  >>>
                  >>>
                  >>> --
                  >>> Dave Sexton
                  >>> dave@www..jwaon line..com
                  >>> -----------------------------------------------------------------------
                  >>> "Richard Blewett [DevelopMentor]" <richardb@NOSPA Mdevelop.com> wrote in
                  >>> message news:uZys5gcTFH A.3952@TK2MSFTN GP15.phx.gbl...
                  >>>> That looks great - apart from I don't understand why you call
                  >>>> DoEvents - how does this help?
                  >>>>
                  >>>> Regards
                  >>>>
                  >>>> Richard Blewett - DevelopMentor
                  >>>> http://www.dotnetconsult.co.uk/weblog
                  >>>>
                  >>>>
                  >>>>
                  >>>> nntp://news.microsoft. com/microsoft.publi c.dotnet.langua ges.csharp/<#mBN3FcTFHA.24 20@TK2MSFTNGP12 .phx.gbl>
                  >>>>
                  >>>> You don't need to use the Thread class to invoke the delegate
                  >>>> asynchronously, however, invoking it using BeginInvoke will execute
                  >>>> the method that the delegate points to on a ThreadPool thread. Also,
                  >>>> ProgressBar (and any other WinForms control) requires most of
                  >>>> its members to be executed/accessed on the thread that the control was
                  >>>> created on. To account for this requirement, a proper
                  >>>> example can't be too simple.
                  >>>>
                  >>>> Here's the simplest approach to updating a progress bar aynchronously
                  >>>> in a WinForms app (the proper way). I'm assuming that each
                  >>>> method is contained by a class derived from System.Windows. Forms.Form:
                  >>>>
                  >>>> private delegate void UpdateProgressI nvoker(int Position);
                  >>>> private System.Windows. Forms.ProgressB ar progressBar;
                  >>>>
                  >>>> /// <summary>Test the progress bar asynchronous update code</summary>
                  >>>> public void DoSomeWork()
                  >>>> {
                  >>>> progressBar.Min imum = 0;
                  >>>> progressBar.Max imum = 100;
                  >>>>
                  >>>> for (int i = 0; i < 10000; i++)
                  >>>> {
                  >>>> // Create a pointer to the UpdateProgress method
                  >>>> UpdateProgressI nvoker del = new UpdateProgressI nvoker(UpdatePr ogress);
                  >>>>
                  >>>> // Invoke the method asynchronously
                  >>>> del.BeginInvoke ((int) (i / 100), null, null);
                  >>>>
                  >>>> // Tell the app to handle pending messages
                  >>>> // (so the form doesn't freeze and the progress bar is updated
                  >>>> visually)
                  >>>> Application.DoE vents();
                  >>>> }
                  >>>> }
                  >>>>
                  >>>>
                  >>>> /// <summary>
                  >>>> /// This method does not update the progress bar directly. Instead, it
                  >>>> ensures that the
                  >>>> /// <see cref="UpdatePro gressCore" /> method (which actually does the
                  >>>> work) is executed on the
                  >>>> /// thread that the ProgressBar was created on.
                  >>>> /// </summary>
                  >>>> private void UpdateProgress( int Position)
                  >>>> {
                  >>>> // Check if the Form.InvokeRequ ired property is true. This will
                  >>>> indicate that
                  >>>> // the currently executing thread is not the thread that the
                  >>>> ProgressBar was created on.
                  >>>> // To update the progress bar synchronously, we will need to invoke the
                  >>>> method on the
                  >>>> // main thread.
                  >>>> // [this] must be a reference to a Form object.
                  >>>> if (!this.InvokeRe quired)
                  >>>> {
                  >>>> // Create a pointer to the UpdateProgressC ore method which performs the
                  >>>> actual update
                  >>>> UpdateProgressI nvoker del = new
                  >>>> UpdateProgressI nvoker(UpdatePr ogressCore);
                  >>>>
                  >>>> // Invoke the method asynchronously on the main thread of the
                  >>>> application.
                  >>>> // By using Form.Invoke, we ensure that our progress bar will be
                  >>>> updated properly.
                  >>>> this.Invoke(del , new object[] { Position });
                  >>>> }
                  >>>> else
                  >>>> // Currently executing thread is the ProgressBar's thread,
                  >>>> // so update the progress bar normally
                  >>>> UpdateProgressC ore(Position);
                  >>>> }
                  >>>>
                  >>>> /// <summary>
                  >>>> /// Do not call this method directly. Instead, call <see
                  >>>> cref="UpdatePro gress" />.
                  >>>> /// </summary>
                  >>>> private void UpdateProgressC ore(int Position)
                  >>>> {
                  >>>> progressBar.Val ue = Position;
                  >>>> }
                  >>>>
                  >>>>
                  >>>> --
                  >>>> Dave Sexton
                  >>>> dave@www..jwaon line..com
                  >>>> -----------------------------------------------------------------------
                  >>>> "Grant" <gpsnett@hotmai l.com> wrote in message
                  >>>> news:Oo0nRtaTFH A.3840@tk2msftn gp13.phx.gbl...
                  >>>> >I am having great difficulty understanding this and any code samples I
                  >>>> >find online are kilometres long and complicated to
                  >>>> >understand...P lease could someone give me a simple exampe of how to
                  >>>> >get a delegate passed to my worked class so that my main form
                  >>>> >can update its progress bar? I know it has something to do with
                  >>>> >begininvoke and endinvoke etc, but I just need a simple sample to
                  >>>> >understand the convention.
                  >>>> >
                  >>>> >
                  >>>> > Code from my main form:
                  >>>> > -----------------------------------
                  >>>> > form1Delegate dlgate = new form1Delegate(I ncreaseProgress Bar);
                  >>>> > //thing.countUpTo aMillionOrSomet hing(new
                  >>>> > form1Delegate(t his.IncreasePro gressBar));
                  >>>> > Thread thread = new Thread(new
                  >>>> > ThreadStart(thi ng.countUpToaMi llionOrSomethin g(dlgate)));
                  >>>> > thread.Start();
                  >>>> > -----------------------------------
                  >>>> >
                  >>>> > Code from my worker class called 'thing'
                  >>>> > -----------------------------------
                  >>>> > public static void countUpToaMilli onOrSomething(F orm1.form1Deleg ate
                  >>>> > myMethodDelegat e)
                  >>>> > {
                  >>>> > int x = 0;
                  >>>> > while ( x < 50)
                  >>>> > {
                  >>>> > Thread.Sleep(70 );
                  >>>> > x ++ ;
                  >>>> > myMethodDelegat e();
                  >>>> > }
                  >>>> > }
                  >>>> > -----------------------------------
                  >>>> >
                  >>>> >
                  >>>> > I can only get it to work synchronously with the following line:
                  >>>> >
                  >>>> > thing.countUpTo aMillionOrSomet hing(new
                  >>>> > form1Delegate(t his.IncreasePro gressBar));
                  >>>> >
                  >>>> > If I try compile with the thread example above it spews about 'Method
                  >>>> > name expected' and underlines the following bit of code:
                  >>>> >
                  >>>> > thing.countUpTo aMillionOrSomet hing(dlgate)
                  >>>> >
                  >>>> > Any help greatly appreciated,
                  >>>> > Thanks,
                  >>>> > Grant
                  >>>> >
                  >>>> >
                  >>>>
                  >>>>
                  >>>>
                  >>>> [microsoft.publi c.dotnet.langua ges.csharp]
                  >>>
                  >>>[/color]
                  >>
                  >>[/color]
                  >
                  >[/color]


                  Comment

                  • Richard Blewett [DevelopMentor]

                    #10
                    Re: Delegates and threads

                    Something like this:

                    using System.Runtime. Remoting.Messag ing; .. for the AsyncCallback class

                    delegate void CountToAMillion Del(Form f);
                    delegate void UpdaterDel();

                    // Main form

                    void button1_Click(o bject sender, EventArgs e)
                    {
                    CountToAMillion Del d = new CountToAMillion Del(countUpToaM illionOrSomethi ng);
                    // run the long running process on a worker thread
                    d.BeginInvoke(p rogressForm, new AsyncCallback(C allback), null); // the callback means we can call EndInvoke
                    }

                    void Callback(IAsync Result ar)
                    {
                    AsyncResult a = (AsyncResult)ar ;
                    CountToAMillion Del d = (CountToAMillio nDel)a.AsyncDel egate;
                    d.EndInvoke(ar) ;
                    }

                    void countUpToaMilli onOrSomething(F orm f)
                    {
                    for(something which takes a while)
                    {
                    if( you need to update thte progress bar)
                    {
                    // From the worker thread update the UI by marshalling the update to the UI thread
                    f.BeginInvoke(n ewUpdaterDel(Up dateProgressBar ), new object[]{}); // this is the Control.BeginIn voke member not Delegate.BeginI nvoke
                    }
                    }
                    }

                    void UpdateProgressB ar()
                    {
                    // perform the progress bar update
                    }

                    This should get you the behaviour you want. Be warned I've only used the Outlook compiler on this ;-) - I typed it into Outlook by hand so there may be minor typos, etc.

                    Regards

                    Richard Blewett - DevelopMentor



                    Yes thats right I need to understand how to pass a delegate to a new thread
                    I have created. I can do it synchronously but not asynchronously. So in the
                    example provided the 'BeginInvoke' command executes that on a seperate
                    thread using the threadpool, however Richard says:
                    ------
                    You example would be much more real world if the worker thread was
                    performing the work and then passing the requests to update the progress bar
                    back to the UI thread via control.Invoke (or BeginInvoke which is preferable
                    in my book)
                    ------

                    That is really what I was after. I have a sepereate static class that does
                    all the work. I need this class to receive the delegate but I dont know how
                    to send it there on the thread I created, which Id like to manage myself and
                    not have it automatically done (I heard DoEvents was evil in VB6, is it the
                    same for .NET?) . Im starting up my own single thread and not using the
                    "threadpool waitcallback" way of creating threads (havent learnt how to to
                    do those just yet). So why does the IDE tell me "Method name
                    expected" when I get to the following line of code:
                    thing.countUpTo aMillionOrSomet hing(dlgate). What method name is it
                    expecting? I have created the delegate (which I understand is a wrapper and
                    points to the progress bar updater function I created on the main form).

                    Thanks for all your help,
                    Cheers,
                    Grant

                    Comment

                    • Dave

                      #11
                      Re: Delegates and threads

                      The code I supplied was to illustrate how to use a delegate asynchronously, in a simple approach. I used a design pattern that
                      would allow the developer to call the "UpdateProgress " method from a class that has a reference to the form without caring about the
                      "logic" involved in updating the Form's controls.

                      Thread-Safety
                      Encapsulation
                      Win32 programming

                      Grant:

                      In my previous code sample I have illustrated how you can use a delegate. I'm sorry if it was unclear. I have attached a simpler
                      approach below.

                      The code below will also address this question:
                      [color=blue]
                      > thing.countUpTo aMillionOrSomet hing(dlgate). What method name is it expecting?[/color]

                      Code example:

                      public delegate void DoSomething();

                      public void countUpToaMilli onOrSomething(D oSomething ThingToDo)
                      {
                      // call the "ThingToDo" asynchronously
                      ThingToDo.Begin Invoke(null, null);
                      }


                      public void TargetOfInvocat ion()
                      {
                      Debug.WriteLine ("Something. ");
                      }


                      public void Test()
                      {
                      countUpToaMilli onOrSomething(n ew DoSomething(Tar getOfInvocation ));

                      // Give the method some time to execute before the Debugger detaches
                      // (If you don't give it a long enough period of time, you may not see the output,
                      // yet the "TargetOfInvoca tion" method will be invoked regardless)
                      System.Threadin g.Thread.Sleep( 1000);
                      }

                      --
                      Dave Sexton
                      dave@www..jwaon line..com
                      -----------------------------------------------------------------------
                      "Grant" <gpsnett@hotmai l.com> wrote in message news:eLbx4SjTFH A.2172@tk2msftn gp13.phx.gbl...[color=blue]
                      > Yes thats right I need to understand how to pass a delegate to a new thread I have created. I can do it synchronously but not
                      > asynchronously. So in the example provided the 'BeginInvoke' command executes that on a seperate thread using the threadpool,
                      > however Richard says:
                      > ------
                      > You example would be much more real world if the worker thread was performing the work and then passing the requests to update the
                      > progress bar back to the UI thread via control.Invoke (or BeginInvoke which is preferable in my book)
                      > ------
                      >
                      > That is really what I was after. I have a sepereate static class that does all the work. I need this class to receive the delegate
                      > but I dont know how to send it there on the thread I created, which Id like to manage myself and not have it automatically done (I
                      > heard DoEvents was evil in VB6, is it the same for .NET?) . Im starting up my own single thread and not using the "threadpool
                      > waitcallback" way of creating threads (havent learnt how to to do those just yet). So why does the IDE tell me "Method name
                      > expected" when I get to the following line of code: thing.countUpTo aMillionOrSomet hing(dlgate). What method name is it expecting?
                      > I have created the delegate (which I understand is a wrapper and points to the progress bar updater function I created on the main
                      > form).
                      >
                      > Thanks for all your help,
                      > Cheers,
                      > Grant
                      >
                      >
                      > "Dave" <NOSPAM-dave@dotcomdata solutions.com> wrote in message news:OuTvKffTFH A.2872@TK2MSFTN GP14.phx.gbl...[color=green]
                      >> Lol. Thanks for the feedback, but does anyone read the initial question anymore??
                      >>[color=darkred]
                      >>> Please could someone give me a simple exampe of how to get a delegate passed to my worked class so that my main form can update
                      >>> its progress bar?[/color]
                      >>
                      >> That's what he wanted. He needed to understand delegates, I assumed.
                      >>
                      >> Anyway... I think you missed the part where i check Form.RequiresIn voke, and if it is false, do the update directly.
                      >> UpdateProgessCo re is exactly what is sounds like... a method to update a progress bar. How do I know he's able to do this in one
                      >> line of code? That's why it's a seperate method.
                      >>
                      >> Encapsulation.
                      >>
                      >> --
                      >> Dave Sexton
                      >> dave@www..jwaon line..com
                      >> -----------------------------------------------------------------------
                      >> "Willy Denoyette [MVP]" <willy.denoyett e@telenet.be> wrote in message news:eK1S$HdTFH A.3140@TK2MSFTN GP14.phx.gbl...[color=darkred]
                      >>> Is there something particular you are trying to prove here?
                      >>> You run 'DoSomeWork' on the main UI thread, in 'DoSomeWork' you call an asynchronous delegate to run 'UpdateProgress ', as this
                      >>> one runs on a thread from the pool you have to marshal the call to 'UpdateProgress Core' (using the synchronous Invoke) so it
                      >>> runs on the UI thread.
                      >>> So basically, you are running a long task on the UI thread , call a delegate to update the UI on another thread and then need to
                      >>> Invoke to marshal the call to the UI is plain silly. No surprise you need to call DoEvents.
                      >>> Agreed, if you do not call DoEvents you'll consume all available pool threads and crash (Invoke doesn't return as the messages
                      >>> don't get dispatched) , but you shouldn't run the task on the UI thread in the first place.
                      >>>
                      >>>
                      >>> Willy.
                      >>>
                      >>>
                      >>>
                      >>>
                      >>> "Dave" <NOSPAM-dave@dotcomdata solutions.com> wrote in message news:%23wx5HucT FHA.616@TK2MSFT NGP12.phx.gbl.. .
                      >>>> Comment out Application.DoE vents and you'll see how it helps.
                      >>>>
                      >>>> Has to do with the fact that Windows uses a "Message Loop" so method invocations for WinForms controls aren't exactly
                      >>>> "real-time". The message loop is like a queue, meaning first-in first-out. Your whole windows app depends on the messages from
                      >>>> the queue reaching the main window procedure in order to process events, such as System.Windows. Forms.Form.Pain t event. Without
                      >>>> this message, the form will never refresh, and neither will it's child controls (i.e. progress bar). User actions are also
                      >>>> messages, so the window would "freeze" up, not allowing you to interact with it, while the "DoSomeWork " method is executing on
                      >>>> the main window thread.
                      >>>>
                      >>>> In other words:
                      >>>> 1. Application.Run starts a message loop
                      >>>> 2. Your Form (main application window) processes messages on the loop
                      >>>> 3. My method (DoSomeWork) blocks the thread, not allowing it to accept messages while it is running
                      >>>> 4. Application.DoE vents allows the Form to process messages currently in the queue, effectively updating the Form while
                      >>>> DoSomeWork is doing some work :)
                      >>>>
                      >>>>
                      >>>>
                      >>>> --
                      >>>> Dave Sexton
                      >>>> dave@www..jwaon line..com
                      >>>> -----------------------------------------------------------------------
                      >>>> "Richard Blewett [DevelopMentor]" <richardb@NOSPA Mdevelop.com> wrote in message news:uZys5gcTFH A.3952@TK2MSFTN GP15.phx.gbl...
                      >>>>> That looks great - apart from I don't understand why you call DoEvents - how does this help?
                      >>>>>
                      >>>>> Regards
                      >>>>>
                      >>>>> Richard Blewett - DevelopMentor
                      >>>>> http://www.dotnetconsult.co.uk/weblog
                      >>>>>
                      >>>>>
                      >>>>>
                      >>>>> nntp://news.microsoft. com/microsoft.publi c.dotnet.langua ges.csharp/<#mBN3FcTFHA.24 20@TK2MSFTNGP12 .phx.gbl>
                      >>>>>
                      >>>>> You don't need to use the Thread class to invoke the delegate asynchronously, however, invoking it using BeginInvoke will
                      >>>>> execute
                      >>>>> the method that the delegate points to on a ThreadPool thread. Also, ProgressBar (and any other WinForms control) requires
                      >>>>> most of
                      >>>>> its members to be executed/accessed on the thread that the control was created on. To account for this requirement, a proper
                      >>>>> example can't be too simple.
                      >>>>>
                      >>>>> Here's the simplest approach to updating a progress bar aynchronously in a WinForms app (the proper way). I'm assuming that
                      >>>>> each
                      >>>>> method is contained by a class derived from System.Windows. Forms.Form:
                      >>>>>
                      >>>>> private delegate void UpdateProgressI nvoker(int Position);
                      >>>>> private System.Windows. Forms.ProgressB ar progressBar;
                      >>>>>
                      >>>>> /// <summary>Test the progress bar asynchronous update code</summary>
                      >>>>> public void DoSomeWork()
                      >>>>> {
                      >>>>> progressBar.Min imum = 0;
                      >>>>> progressBar.Max imum = 100;
                      >>>>>
                      >>>>> for (int i = 0; i < 10000; i++)
                      >>>>> {
                      >>>>> // Create a pointer to the UpdateProgress method
                      >>>>> UpdateProgressI nvoker del = new UpdateProgressI nvoker(UpdatePr ogress);
                      >>>>>
                      >>>>> // Invoke the method asynchronously
                      >>>>> del.BeginInvoke ((int) (i / 100), null, null);
                      >>>>>
                      >>>>> // Tell the app to handle pending messages
                      >>>>> // (so the form doesn't freeze and the progress bar is updated visually)
                      >>>>> Application.DoE vents();
                      >>>>> }
                      >>>>> }
                      >>>>>
                      >>>>>
                      >>>>> /// <summary>
                      >>>>> /// This method does not update the progress bar directly. Instead, it ensures that the
                      >>>>> /// <see cref="UpdatePro gressCore" /> method (which actually does the work) is executed on the
                      >>>>> /// thread that the ProgressBar was created on.
                      >>>>> /// </summary>
                      >>>>> private void UpdateProgress( int Position)
                      >>>>> {
                      >>>>> // Check if the Form.InvokeRequ ired property is true. This will indicate that
                      >>>>> // the currently executing thread is not the thread that the ProgressBar was created on.
                      >>>>> // To update the progress bar synchronously, we will need to invoke the method on the
                      >>>>> // main thread.
                      >>>>> // [this] must be a reference to a Form object.
                      >>>>> if (!this.InvokeRe quired)
                      >>>>> {
                      >>>>> // Create a pointer to the UpdateProgressC ore method which performs the actual update
                      >>>>> UpdateProgressI nvoker del = new UpdateProgressI nvoker(UpdatePr ogressCore);
                      >>>>>
                      >>>>> // Invoke the method asynchronously on the main thread of the application.
                      >>>>> // By using Form.Invoke, we ensure that our progress bar will be updated properly.
                      >>>>> this.Invoke(del , new object[] { Position });
                      >>>>> }
                      >>>>> else
                      >>>>> // Currently executing thread is the ProgressBar's thread,
                      >>>>> // so update the progress bar normally
                      >>>>> UpdateProgressC ore(Position);
                      >>>>> }
                      >>>>>
                      >>>>> /// <summary>
                      >>>>> /// Do not call this method directly. Instead, call <see cref="UpdatePro gress" />.
                      >>>>> /// </summary>
                      >>>>> private void UpdateProgressC ore(int Position)
                      >>>>> {
                      >>>>> progressBar.Val ue = Position;
                      >>>>> }
                      >>>>>
                      >>>>>
                      >>>>> --
                      >>>>> Dave Sexton
                      >>>>> dave@www..jwaon line..com
                      >>>>> -----------------------------------------------------------------------
                      >>>>> "Grant" <gpsnett@hotmai l.com> wrote in message news:Oo0nRtaTFH A.3840@tk2msftn gp13.phx.gbl...
                      >>>>> >I am having great difficulty understanding this and any code samples I find online are kilometres long and complicated to
                      >>>>> >understand...P lease could someone give me a simple exampe of how to get a delegate passed to my worked class so that my main
                      >>>>> >form
                      >>>>> >can update its progress bar? I know it has something to do with begininvoke and endinvoke etc, but I just need a simple
                      >>>>> >sample to
                      >>>>> >understand the convention.
                      >>>>> >
                      >>>>> >
                      >>>>> > Code from my main form:
                      >>>>> > -----------------------------------
                      >>>>> > form1Delegate dlgate = new form1Delegate(I ncreaseProgress Bar);
                      >>>>> > //thing.countUpTo aMillionOrSomet hing(new form1Delegate(t his.IncreasePro gressBar));
                      >>>>> > Thread thread = new Thread(new ThreadStart(thi ng.countUpToaMi llionOrSomethin g(dlgate)));
                      >>>>> > thread.Start();
                      >>>>> > -----------------------------------
                      >>>>> >
                      >>>>> > Code from my worker class called 'thing'
                      >>>>> > -----------------------------------
                      >>>>> > public static void countUpToaMilli onOrSomething(F orm1.form1Deleg ate myMethodDelegat e)
                      >>>>> > {
                      >>>>> > int x = 0;
                      >>>>> > while ( x < 50)
                      >>>>> > {
                      >>>>> > Thread.Sleep(70 );
                      >>>>> > x ++ ;
                      >>>>> > myMethodDelegat e();
                      >>>>> > }
                      >>>>> > }
                      >>>>> > -----------------------------------
                      >>>>> >
                      >>>>> >
                      >>>>> > I can only get it to work synchronously with the following line:
                      >>>>> >
                      >>>>> > thing.countUpTo aMillionOrSomet hing(new form1Delegate(t his.IncreasePro gressBar));
                      >>>>> >
                      >>>>> > If I try compile with the thread example above it spews about 'Method name expected' and underlines the following bit of
                      >>>>> > code:
                      >>>>> >
                      >>>>> > thing.countUpTo aMillionOrSomet hing(dlgate)
                      >>>>> >
                      >>>>> > Any help greatly appreciated,
                      >>>>> > Thanks,
                      >>>>> > Grant
                      >>>>> >
                      >>>>> >
                      >>>>>
                      >>>>>
                      >>>>>
                      >>>>> [microsoft.publi c.dotnet.langua ges.csharp]
                      >>>>
                      >>>>
                      >>>
                      >>>[/color]
                      >>
                      >>[/color]
                      >
                      >[/color]


                      Comment

                      • Grant

                        #12
                        Re: Delegates and threads

                        Thanks for all your help with this. I had to change the 'progressForm' and
                        replace with 'this' which worked. I have a better understanding of this just
                        from looking at code.

                        Thanks again,
                        Grant

                        "Richard Blewett [DevelopMentor]" <richardb@NOSPA Mdevelop.com> wrote in
                        message news:ezGt3tjTFH A.3012@TK2MSFTN GP14.phx.gbl...[color=blue]
                        > Something like this:
                        >
                        > using System.Runtime. Remoting.Messag ing; .. for the AsyncCallback class
                        >
                        > delegate void CountToAMillion Del(Form f);
                        > delegate void UpdaterDel();
                        >
                        > // Main form
                        >
                        > void button1_Click(o bject sender, EventArgs e)
                        > {
                        > CountToAMillion Del d = new
                        > CountToAMillion Del(countUpToaM illionOrSomethi ng);
                        > // run the long running process on a worker thread
                        > d.BeginInvoke(p rogressForm, new AsyncCallback(C allback), null); // the
                        > callback means we can call EndInvoke
                        > }
                        >
                        > void Callback(IAsync Result ar)
                        > {
                        > AsyncResult a = (AsyncResult)ar ;
                        > CountToAMillion Del d = (CountToAMillio nDel)a.AsyncDel egate;
                        > d.EndInvoke(ar) ;
                        > }
                        >
                        > void countUpToaMilli onOrSomething(F orm f)
                        > {
                        > for(something which takes a while)
                        > {
                        > if( you need to update thte progress bar)
                        > {
                        > // From the worker thread update the UI by marshalling the update to the
                        > UI thread
                        > f.BeginInvoke(n ewUpdaterDel(Up dateProgressBar ), new object[]{}); // this
                        > is the Control.BeginIn voke member not Delegate.BeginI nvoke
                        > }
                        > }
                        > }
                        >
                        > void UpdateProgressB ar()
                        > {
                        > // perform the progress bar update
                        > }
                        >
                        > This should get you the behaviour you want. Be warned I've only used the
                        > Outlook compiler on this ;-) - I typed it into Outlook by hand so there
                        > may be minor typos, etc.
                        >
                        > Regards
                        >
                        > Richard Blewett - DevelopMentor
                        > http://www.dotnetconsult.co.uk/weblog
                        > http://www.dotnetconsult.co.uk
                        >
                        > Yes thats right I need to understand how to pass a delegate to a new
                        > thread
                        > I have created. I can do it synchronously but not asynchronously. So in
                        > the
                        > example provided the 'BeginInvoke' command executes that on a seperate
                        > thread using the threadpool, however Richard says:
                        > ------
                        > You example would be much more real world if the worker thread was
                        > performing the work and then passing the requests to update the progress
                        > bar
                        > back to the UI thread via control.Invoke (or BeginInvoke which is
                        > preferable
                        > in my book)
                        > ------
                        >
                        > That is really what I was after. I have a sepereate static class that does
                        > all the work. I need this class to receive the delegate but I dont know
                        > how
                        > to send it there on the thread I created, which Id like to manage myself
                        > and
                        > not have it automatically done (I heard DoEvents was evil in VB6, is it
                        > the
                        > same for .NET?) . Im starting up my own single thread and not using the
                        > "threadpool waitcallback" way of creating threads (havent learnt how to to
                        > do those just yet). So why does the IDE tell me "Method name
                        > expected" when I get to the following line of code:
                        > thing.countUpTo aMillionOrSomet hing(dlgate). What method name is it
                        > expecting? I have created the delegate (which I understand is a wrapper
                        > and
                        > points to the progress bar updater function I created on the main form).
                        >
                        > Thanks for all your help,
                        > Cheers,
                        > Grant
                        >[/color]


                        Comment

                        • Grant

                          #13
                          Re: Delegates and threads

                          Dave, thanks for replying to my original post. Im sure there are many ways
                          to achieve the same thing and at the end of the day Ill learn whatever
                          works. Ive copied your code and Richards code, both of which have shown me
                          how delegates and asynchronous operations work.

                          Thanks for your help,
                          Grant

                          "Dave" <NOSPAM-dave@dotcomdata solutions.com> wrote in message
                          news:%23MAqgpkT FHA.3840@tk2msf tngp13.phx.gbl. ..[color=blue]
                          > The code I supplied was to illustrate how to use a delegate
                          > asynchronously, in a simple approach. I used a design pattern that would
                          > allow the developer to call the "UpdateProgress " method from a class that
                          > has a reference to the form without caring about the "logic" involved in
                          > updating the Form's controls.
                          >
                          > Thread-Safety
                          > Encapsulation
                          > Win32 programming
                          >
                          > Grant:
                          >
                          > In my previous code sample I have illustrated how you can use a delegate.
                          > I'm sorry if it was unclear. I have attached a simpler approach below.
                          >
                          > The code below will also address this question:
                          >[color=green]
                          >> thing.countUpTo aMillionOrSomet hing(dlgate). What method name is it
                          >> expecting?[/color]
                          >
                          > Code example:
                          >
                          > public delegate void DoSomething();
                          >
                          > public void countUpToaMilli onOrSomething(D oSomething ThingToDo)
                          > {
                          > // call the "ThingToDo" asynchronously
                          > ThingToDo.Begin Invoke(null, null);
                          > }
                          >
                          >
                          > public void TargetOfInvocat ion()
                          > {
                          > Debug.WriteLine ("Something. ");
                          > }
                          >
                          >
                          > public void Test()
                          > {
                          > countUpToaMilli onOrSomething(n ew DoSomething(Tar getOfInvocation ));
                          >
                          > // Give the method some time to execute before the Debugger detaches
                          > // (If you don't give it a long enough period of time, you may not see the
                          > output,
                          > // yet the "TargetOfInvoca tion" method will be invoked regardless)
                          > System.Threadin g.Thread.Sleep( 1000);
                          > }
                          >
                          > --
                          > Dave Sexton
                          > dave@www..jwaon line..com
                          > -----------------------------------------------------------------------
                          > "Grant" <gpsnett@hotmai l.com> wrote in message
                          > news:eLbx4SjTFH A.2172@tk2msftn gp13.phx.gbl...[color=green]
                          >> Yes thats right I need to understand how to pass a delegate to a new
                          >> thread I have created. I can do it synchronously but not asynchronously.
                          >> So in the example provided the 'BeginInvoke' command executes that on a
                          >> seperate thread using the threadpool, however Richard says:
                          >> ------
                          >> You example would be much more real world if the worker thread was
                          >> performing the work and then passing the requests to update the progress
                          >> bar back to the UI thread via control.Invoke (or BeginInvoke which is
                          >> preferable in my book)
                          >> ------
                          >>
                          >> That is really what I was after. I have a sepereate static class that
                          >> does all the work. I need this class to receive the delegate but I dont
                          >> know how to send it there on the thread I created, which Id like to
                          >> manage myself and not have it automatically done (I heard DoEvents was
                          >> evil in VB6, is it the same for .NET?) . Im starting up my own single
                          >> thread and not using the "threadpool waitcallback" way of creating
                          >> threads (havent learnt how to to do those just yet). So why does the IDE
                          >> tell me "Method name
                          >> expected" when I get to the following line of code:
                          >> thing.countUpTo aMillionOrSomet hing(dlgate). What method name is it
                          >> expecting? I have created the delegate (which I understand is a wrapper
                          >> and points to the progress bar updater function I created on the main
                          >> form).
                          >>
                          >> Thanks for all your help,
                          >> Cheers,
                          >> Grant
                          >>
                          >>
                          >> "Dave" <NOSPAM-dave@dotcomdata solutions.com> wrote in message
                          >> news:OuTvKffTFH A.2872@TK2MSFTN GP14.phx.gbl...[color=darkred]
                          >>> Lol. Thanks for the feedback, but does anyone read the initial question
                          >>> anymore??
                          >>>
                          >>>> Please could someone give me a simple exampe of how to get a delegate
                          >>>> passed to my worked class so that my main form can update its progress
                          >>>> bar?
                          >>>
                          >>> That's what he wanted. He needed to understand delegates, I assumed.
                          >>>
                          >>> Anyway... I think you missed the part where i check Form.RequiresIn voke,
                          >>> and if it is false, do the update directly.
                          >>> UpdateProgessCo re is exactly what is sounds like... a method to update a
                          >>> progress bar. How do I know he's able to do this in one line of code?
                          >>> That's why it's a seperate method.
                          >>>
                          >>> Encapsulation.
                          >>>
                          >>> --
                          >>> Dave Sexton
                          >>> dave@www..jwaon line..com
                          >>> -----------------------------------------------------------------------
                          >>> "Willy Denoyette [MVP]" <willy.denoyett e@telenet.be> wrote in message
                          >>> news:eK1S$HdTFH A.3140@TK2MSFTN GP14.phx.gbl...
                          >>>> Is there something particular you are trying to prove here?
                          >>>> You run 'DoSomeWork' on the main UI thread, in 'DoSomeWork' you call an
                          >>>> asynchronous delegate to run 'UpdateProgress ', as this one runs on a
                          >>>> thread from the pool you have to marshal the call to
                          >>>> 'UpdateProgress Core' (using the synchronous Invoke) so it runs on the
                          >>>> UI thread.
                          >>>> So basically, you are running a long task on the UI thread , call a
                          >>>> delegate to update the UI on another thread and then need to Invoke to
                          >>>> marshal the call to the UI is plain silly. No surprise you need to call
                          >>>> DoEvents.
                          >>>> Agreed, if you do not call DoEvents you'll consume all available pool
                          >>>> threads and crash (Invoke doesn't return as the messages don't get
                          >>>> dispatched) , but you shouldn't run the task on the UI thread in the
                          >>>> first place.
                          >>>>
                          >>>>
                          >>>> Willy.
                          >>>>
                          >>>>
                          >>>>
                          >>>>
                          >>>> "Dave" <NOSPAM-dave@dotcomdata solutions.com> wrote in message
                          >>>> news:%23wx5HucT FHA.616@TK2MSFT NGP12.phx.gbl.. .
                          >>>>> Comment out Application.DoE vents and you'll see how it helps.
                          >>>>>
                          >>>>> Has to do with the fact that Windows uses a "Message Loop" so method
                          >>>>> invocations for WinForms controls aren't exactly "real-time". The
                          >>>>> message loop is like a queue, meaning first-in first-out. Your whole
                          >>>>> windows app depends on the messages from the queue reaching the main
                          >>>>> window procedure in order to process events, such as
                          >>>>> System.Windows. Forms.Form.Pain t event. Without this message, the form
                          >>>>> will never refresh, and neither will it's child controls (i.e.
                          >>>>> progress bar). User actions are also messages, so the window would
                          >>>>> "freeze" up, not allowing you to interact with it, while the
                          >>>>> "DoSomeWork " method is executing on the main window thread.
                          >>>>>
                          >>>>> In other words:
                          >>>>> 1. Application.Run starts a message loop
                          >>>>> 2. Your Form (main application window) processes messages on the
                          >>>>> loop
                          >>>>> 3. My method (DoSomeWork) blocks the thread, not allowing it to
                          >>>>> accept messages while it is running
                          >>>>> 4. Application.DoE vents allows the Form to process messages
                          >>>>> currently in the queue, effectively updating the Form while DoSomeWork
                          >>>>> is doing some work :)
                          >>>>>
                          >>>>>
                          >>>>>
                          >>>>> --
                          >>>>> Dave Sexton
                          >>>>> dave@www..jwaon line..com
                          >>>>> -----------------------------------------------------------------------
                          >>>>> "Richard Blewett [DevelopMentor]" <richardb@NOSPA Mdevelop.com> wrote
                          >>>>> in message news:uZys5gcTFH A.3952@TK2MSFTN GP15.phx.gbl...
                          >>>>>> That looks great - apart from I don't understand why you call
                          >>>>>> DoEvents - how does this help?
                          >>>>>>
                          >>>>>> Regards
                          >>>>>>
                          >>>>>> Richard Blewett - DevelopMentor
                          >>>>>> http://www.dotnetconsult.co.uk/weblog
                          >>>>>>
                          >>>>>>
                          >>>>>>
                          >>>>>> nntp://news.microsoft. com/microsoft.publi c.dotnet.langua ges.csharp/<#mBN3FcTFHA.24 20@TK2MSFTNGP12 .phx.gbl>
                          >>>>>>
                          >>>>>> You don't need to use the Thread class to invoke the delegate
                          >>>>>> asynchronously, however, invoking it using BeginInvoke will execute
                          >>>>>> the method that the delegate points to on a ThreadPool thread. Also,
                          >>>>>> ProgressBar (and any other WinForms control) requires most of
                          >>>>>> its members to be executed/accessed on the thread that the control
                          >>>>>> was created on. To account for this requirement, a proper
                          >>>>>> example can't be too simple.
                          >>>>>>
                          >>>>>> Here's the simplest approach to updating a progress bar aynchronously
                          >>>>>> in a WinForms app (the proper way). I'm assuming that each
                          >>>>>> method is contained by a class derived from
                          >>>>>> System.Windows. Forms.Form:
                          >>>>>>
                          >>>>>> private delegate void UpdateProgressI nvoker(int Position);
                          >>>>>> private System.Windows. Forms.ProgressB ar progressBar;
                          >>>>>>
                          >>>>>> /// <summary>Test the progress bar asynchronous update code</summary>
                          >>>>>> public void DoSomeWork()
                          >>>>>> {
                          >>>>>> progressBar.Min imum = 0;
                          >>>>>> progressBar.Max imum = 100;
                          >>>>>>
                          >>>>>> for (int i = 0; i < 10000; i++)
                          >>>>>> {
                          >>>>>> // Create a pointer to the UpdateProgress method
                          >>>>>> UpdateProgressI nvoker del = new
                          >>>>>> UpdateProgressI nvoker(UpdatePr ogress);
                          >>>>>>
                          >>>>>> // Invoke the method asynchronously
                          >>>>>> del.BeginInvoke ((int) (i / 100), null, null);
                          >>>>>>
                          >>>>>> // Tell the app to handle pending messages
                          >>>>>> // (so the form doesn't freeze and the progress bar is updated
                          >>>>>> visually)
                          >>>>>> Application.DoE vents();
                          >>>>>> }
                          >>>>>> }
                          >>>>>>
                          >>>>>>
                          >>>>>> /// <summary>
                          >>>>>> /// This method does not update the progress bar directly. Instead,
                          >>>>>> it ensures that the
                          >>>>>> /// <see cref="UpdatePro gressCore" /> method (which actually does the
                          >>>>>> work) is executed on the
                          >>>>>> /// thread that the ProgressBar was created on.
                          >>>>>> /// </summary>
                          >>>>>> private void UpdateProgress( int Position)
                          >>>>>> {
                          >>>>>> // Check if the Form.InvokeRequ ired property is true. This will
                          >>>>>> indicate that
                          >>>>>> // the currently executing thread is not the thread that the
                          >>>>>> ProgressBar was created on.
                          >>>>>> // To update the progress bar synchronously, we will need to invoke
                          >>>>>> the method on the
                          >>>>>> // main thread.
                          >>>>>> // [this] must be a reference to a Form object.
                          >>>>>> if (!this.InvokeRe quired)
                          >>>>>> {
                          >>>>>> // Create a pointer to the UpdateProgressC ore method which performs
                          >>>>>> the actual update
                          >>>>>> UpdateProgressI nvoker del = new
                          >>>>>> UpdateProgressI nvoker(UpdatePr ogressCore);
                          >>>>>>
                          >>>>>> // Invoke the method asynchronously on the main thread of the
                          >>>>>> application.
                          >>>>>> // By using Form.Invoke, we ensure that our progress bar will be
                          >>>>>> updated properly.
                          >>>>>> this.Invoke(del , new object[] { Position });
                          >>>>>> }
                          >>>>>> else
                          >>>>>> // Currently executing thread is the ProgressBar's thread,
                          >>>>>> // so update the progress bar normally
                          >>>>>> UpdateProgressC ore(Position);
                          >>>>>> }
                          >>>>>>
                          >>>>>> /// <summary>
                          >>>>>> /// Do not call this method directly. Instead, call <see
                          >>>>>> cref="UpdatePro gress" />.
                          >>>>>> /// </summary>
                          >>>>>> private void UpdateProgressC ore(int Position)
                          >>>>>> {
                          >>>>>> progressBar.Val ue = Position;
                          >>>>>> }
                          >>>>>>
                          >>>>>>
                          >>>>>> --
                          >>>>>> Dave Sexton
                          >>>>>> dave@www..jwaon line..com
                          >>>>>> -----------------------------------------------------------------------
                          >>>>>> "Grant" <gpsnett@hotmai l.com> wrote in message
                          >>>>>> news:Oo0nRtaTFH A.3840@tk2msftn gp13.phx.gbl...
                          >>>>>> >I am having great difficulty understanding this and any code samples
                          >>>>>> >I find online are kilometres long and complicated to
                          >>>>>> >understand...P lease could someone give me a simple exampe of how to
                          >>>>>> >get a delegate passed to my worked class so that my main form
                          >>>>>> >can update its progress bar? I know it has something to do with
                          >>>>>> >begininvoke and endinvoke etc, but I just need a simple sample to
                          >>>>>> >understand the convention.
                          >>>>>> >
                          >>>>>> >
                          >>>>>> > Code from my main form:
                          >>>>>> > -----------------------------------
                          >>>>>> > form1Delegate dlgate = new form1Delegate(I ncreaseProgress Bar);
                          >>>>>> > //thing.countUpTo aMillionOrSomet hing(new
                          >>>>>> > form1Delegate(t his.IncreasePro gressBar));
                          >>>>>> > Thread thread = new Thread(new
                          >>>>>> > ThreadStart(thi ng.countUpToaMi llionOrSomethin g(dlgate)));
                          >>>>>> > thread.Start();
                          >>>>>> > -----------------------------------
                          >>>>>> >
                          >>>>>> > Code from my worker class called 'thing'
                          >>>>>> > -----------------------------------
                          >>>>>> > public static void countUpToaMilli onOrSomething(F orm1.form1Deleg ate
                          >>>>>> > myMethodDelegat e)
                          >>>>>> > {
                          >>>>>> > int x = 0;
                          >>>>>> > while ( x < 50)
                          >>>>>> > {
                          >>>>>> > Thread.Sleep(70 );
                          >>>>>> > x ++ ;
                          >>>>>> > myMethodDelegat e();
                          >>>>>> > }
                          >>>>>> > }
                          >>>>>> > -----------------------------------
                          >>>>>> >
                          >>>>>> >
                          >>>>>> > I can only get it to work synchronously with the following line:
                          >>>>>> >
                          >>>>>> > thing.countUpTo aMillionOrSomet hing(new
                          >>>>>> > form1Delegate(t his.IncreasePro gressBar));
                          >>>>>> >
                          >>>>>> > If I try compile with the thread example above it spews about
                          >>>>>> > 'Method name expected' and underlines the following bit of code:
                          >>>>>> >
                          >>>>>> > thing.countUpTo aMillionOrSomet hing(dlgate)
                          >>>>>> >
                          >>>>>> > Any help greatly appreciated,
                          >>>>>> > Thanks,
                          >>>>>> > Grant
                          >>>>>> >
                          >>>>>> >
                          >>>>>>
                          >>>>>>
                          >>>>>>
                          >>>>>> [microsoft.publi c.dotnet.langua ges.csharp]
                          >>>>>
                          >>>>>
                          >>>>
                          >>>>
                          >>>
                          >>>[/color]
                          >>
                          >>[/color]
                          >
                          >[/color]


                          Comment

                          Working...