Set up Display on status line with Threading

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

    Set up Display on status line with Threading

    I have a Windows App that is doing some work and then writing a "Now
    Processing..." line to the status line of the window as well as the Textbox
    on the form.

    But the problem is that the work is in another class from the main class.
    So it couldn't access the Status Line or textbox.

    So what we did was set them up as properties:

    string IStatusDisplay. Status
    {
    get
    {
    return Status.Text;
    }
    set
    {
    Status.Text = value;
    }
    }

    string IStatusDisplay. StatusBar
    {
    get
    {
    return toolStripStatus Label1.Text;
    }
    set
    {
    toolStripStatus Label1.Text = value;
    this.Refresh();
    }
    }

    Then in my code I would call it like:

    Maintenance.Che ckAll(this);

    And the function is:

    public static void CheckAll(IStatu sDisplay display)
    {
    ...
    display.StatusB ar = "Now Processing... " +
    Path.GetFileNam e(file);

    display.Status += file + Environment.New Line;

    }

    This works fine until you try to set it up and call it from a thread - for
    one thing you can't use the this.Refresh() because you get an error:

    this.Refresh();

    Gets me this error:

    Cross-thread operation not valid: Control 'FieldNameMapSe tup'
    accessed from a thread other than the thread it was created on.

    Here I am in another function doing a - "display.Status Bar". It is
    executing the above property until it hits the "this" statement.



    or if you access a button on the page like:

    btnExit.Enabled = true;

    I get the error:
    Cross-thread operation not valid: Control 'btnExit' accessed
    from a thread other than the thread it was created on.

    I am trying to find out how to access the controls on the Form from either
    the same class or a different class (which was why we were passing "this" to
    the other class).

    This all works fine until you put it in a thread.

    Thanks,

    Tom


  • JTC^..^

    #2
    Re: Set up Display on status line with Threading

    On 11 Oct, 06:23, "tshad" <t...@dslextrem e.comwrote:
    I have a Windows App that is doing some work and then writing a "Now
    Processing..." line to the status line of the window as well as the Textbox
    on the form.
    >
    But the problem is that the work is in another class from the main class.
    So it couldn't access the Status Line or textbox.
    >
    So what we did was set them up as properties:
    >
            string IStatusDisplay. Status
            {
                get
                {
                    return Status.Text;
                }
                set
                {
                    Status.Text = value;
                }
            }
    >
            string IStatusDisplay. StatusBar
            {
                get
                {
                    return toolStripStatus Label1.Text;
                }
                set
                {
                    toolStripStatus Label1.Text = value;
                    this.Refresh();
                }
            }
    >
    Then in my code I would call it like:
    >
           Maintenance.Che ckAll(this);
    >
    And the function is:
    >
            public static void CheckAll(IStatu sDisplay display)
            {
                ...
                    display.StatusB ar = "Now Processing... " +
    Path.GetFileNam e(file);
    >
                    display.Status += file + Environment.New Line;
    >
            }
    >
    This works fine until you try to set it up and call it from a thread - for
    one thing you can't use the this.Refresh() because you get an error:
    >
                    this.Refresh();
    >
    Gets me this error:
    >
            Cross-thread operation not valid: Control 'FieldNameMapSe tup'
    accessed from a thread other than the thread it was created on.
    >
    Here I am in another function doing a - "display.Status Bar".  It is
    executing the above property until it hits the "this" statement.
    >
    or if you access a button on the page like:
    >
                btnExit.Enabled = true;
    >
    I get the error:
                Cross-thread operation not valid: Control 'btnExit' accessed
    from a thread other than the thread it was created on.
    >
    I am trying to find out how to access the controls on the Form from either
    the same class or a different class (which was why we were passing "this"to
    the other class).
    >
    This all works fine until you put it in a thread.
    >
    Thanks,
    >
    Tom
    As a solution to getting the status from one class to another use
    events. The event notifies the form (or any other classes using the
    class) of the status change. Call a method to trigger the event.. e.g.
    OnStatusChanged ()

    Your class would contain an event something like this....

    public event EventHandler StatusChanged;
    private void OnStatusChanged ()
    {
    EventHandler handler = StatusChanged;

    if(handler != null)
    {
    EventArgs args = new EventArgs();
    handler(this, args);
    }
    }

    Your form code will look something like this. Where you instantiate
    the class subscribe to the event.

    .....
    MyClass class = new MyClass();
    class.StatusCha nged += new
    StatusChangedEv entHandler(clas s_StatusChanged EventHandler);
    ....
    }

    private void class_StatusCha ngedEventHandle r(object sender, EventArgs
    e)
    {
    this.lblStatus. Text = ((MyClass)sende r).Status;
    }

    Comment

    • Peter Duniho

      #3
      Re: Set up Display on status line with Threading

      On Fri, 10 Oct 2008 22:23:06 -0700, tshad <tfs@dslextreme .comwrote:
      [...]
      I get the error:
      Cross-thread operation not valid: Control 'btnExit' accessed
      from a thread other than the thread it was created on.
      >
      I am trying to find out how to access the controls on the Form from
      either
      the same class or a different class (which was why we were passing
      "this" to
      the other class).
      >
      This all works fine until you put it in a thread.
      That's because you need to use Control.Invoke( ) or Control.BeginIn voke()
      to execute the code that actually has to touch the control itself.

      The other reply doesn't really address this. That reply is not a lot
      different from your own attempt to solve the issue with a property, in
      that it's just an alternate route to the same code, ultimately with the
      same problem: it will try to interact with the control from a thread other
      than the one that owns that control.

      Without a concise-but-complete code sample to work with, it's difficult to
      propose a precise change for your particular scenario. But, as an
      example, you might modify your IStatusDisplay. Status property so that it
      looks like this:

      string IStatusDisplay. Status
      {
      get
      {
      return (string)Status. Invoke((MethodI nvoker)delegate {
      return Status.Text; });
      }
      set
      {
      Status.Invoke(( MethodInvoker)d elegate { Status.Text =
      value });
      }
      }

      That will ensure that the code inside the getter and setter that actually
      interacts with the control instance is always executed on the same thread
      that created your Status control instance.

      You can apply a similar approach everywhere that you need to access
      Control instances from a worker thread.

      By the way, I note that your code actually uses the getter for the Status
      property. Again, without a concise-but-complete code sample it's
      difficult to make precise statements, but on the face of it this looks
      like something that might be a performance issue. In particular, because
      of the need to use Control.Invoke( ), you tie the execution paths of your
      two threads together, preventing them from working independently.

      You might find that it makes more sense for the code that's actually
      changing the status to maintain its own cache of the current status
      string, and then just set that on the Status control. At a minimum, that
      would get rid of one synchronizing round-trip, and you could even use
      Control.BeginIn voke() in the setter, avoiding synchronization issues there
      too.

      Pete

      Comment

      • tshad

        #4
        Re: Set up Display on status line with Threading


        "Peter Duniho" <NpOeStPeAdM@nn owslpianmk.comw rote in message
        news:op.uiunnls k8jd0ej@petes-computer.local. ..
        On Fri, 10 Oct 2008 22:23:06 -0700, tshad <tfs@dslextreme .comwrote:
        >
        >[...]
        >I get the error:
        > Cross-thread operation not valid: Control 'btnExit' accessed
        >from a thread other than the thread it was created on.
        >>
        >I am trying to find out how to access the controls on the Form from
        >either
        >the same class or a different class (which was why we were passing
        >"this" to
        >the other class).
        >>
        >This all works fine until you put it in a thread.
        >
        That's because you need to use Control.Invoke( ) or Control.BeginIn voke()
        to execute the code that actually has to touch the control itself.
        >
        The other reply doesn't really address this. That reply is not a lot
        different from your own attempt to solve the issue with a property, in
        that it's just an alternate route to the same code, ultimately with the
        same problem: it will try to interact with the control from a thread other
        than the one that owns that control.
        >
        Without a concise-but-complete code sample to work with, it's difficult to
        propose a precise change for your particular scenario. But, as an
        example, you might modify your IStatusDisplay. Status property so that it
        looks like this:
        [snip]

        Ok, here is a stripped down sample that consists of 3 buttons, a textbox,
        statusbar and toolStripStatus Label.

        I have 2 files (form1 and Maintenance). In form1 I am calling a function in
        Maintenance that just writes to the textbox and the toolStripStatus Label.
        The first button calls the function without a thread and the second with a
        thread.

        I also have a this.Refresh() in the code to display on the page correctly
        when not running in the thread, but in the thread it gives me the error:

        Cross-thread operation not valid: Control 'Form1' accessed from a thread
        other than the thread it was created on.

        If I comment it out, and run the threading, I get the following when the
        program tries to write to the textbox (Status) from the Maintenance
        function:

        display.Status += file + Environment.New Line;

        Calls this to set the value

        set
        {
        Status.Text = value;
        }


        And get the error:

        Cross-thread operation not valid: Control 'Status' accessed from a
        thread other than the thread it was created on.

        but I don't get the error when setting the toolStripStatus Label from the
        Maintenance function:

        display.StatusB ar = "Now Processing... " + file;

        Why is that? They are both using the "this" that was passed.

        Just trying to understand the different ways to do this so I can choose the
        right way in other situations as well.

        The 3 files in my project are:
        form1.cs
        *************** *************** *************** *******
        using System;
        using System.Threadin g;
        using System.Collecti ons.Generic;
        using System.Componen tModel;
        using System.Data;
        using System.Drawing;
        using System.Linq;
        using System.Text;
        using System.Windows. Forms;

        namespace ControlAccessAc rossClasses
        {
        public partial class Form1 : Form, IStatusDisplay
        {
        public Form1()
        {
        InitializeCompo nent();
        }

        private void Form1_Load(obje ct sender, EventArgs e)
        {
        toolStripStatus Label1.Text = "This is a test";
        }

        #region IStatusDisplay Members

        string IStatusDisplay. Status
        {
        get
        {
        return Status.Text;
        }
        set
        {
        Status.Text = value;
        }
        }

        string IStatusDisplay. StatusBar
        {
        get
        {
        return toolStripStatus Label1.Text;
        }
        set
        {
        toolStripStatus Label1.Text = value;
        //this.Refresh();
        }
        }
        #endregion

        private void WithoutThreadBu tton_Click(obje ct sender, EventArgs e)
        {
        Maintenance.Che ckAll(this);
        }

        private void WithThreadButto n_Click(object sender, EventArgs e)
        {
        Thread oThread = new Thread(new ThreadStart(Cal lWithThread));
        oThread.Start() ;
        }

        private void CallWithThread( )
        {
        Maintenance.Che ckAll(this);
        }

        private void Exit_Click(obje ct sender, EventArgs e)
        {
        Application.Exi t();
        }
        }
        }
        *************** *************** *************** *************** ***
        maintenance.cs
        *************** *************** *************** *************** **
        using System;
        using System.Collecti ons.Generic;
        using System.Linq;
        using System.Text;

        namespace ControlAccessAc rossClasses
        {
        class Maintenance
        {
        public static void CheckAll(IStatu sDisplay display)
        {
        String file = "12345.txt" ;
        display.StatusB ar = "Now Processing... " + file;
        display.Status += file + Environment.New Line;
        }

        }
        public interface IStatusDisplay
        {
        string Status { get; set; }
        string StatusBar { get; set; }
        }
        }
        *************** *************** *************** *************** **

        And the form1.designer. cs
        *************** *************** *************** *************** *
        namespace ControlAccessAc rossClasses
        {
        partial class Form1
        {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.Componen tModel.IContain er components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing ">true if managed resources should be
        disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
        if (disposing && (components != null))
        {
        components.Disp ose();
        }
        base.Dispose(di sposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeCompo nent()
        {
        this.Status = new System.Windows. Forms.TextBox() ;
        this.statusStri p1 = new System.Windows. Forms.StatusStr ip();
        this.toolStripS tatusLabel1 = new
        System.Windows. Forms.ToolStrip StatusLabel();
        this.WithThread Button = new System.Windows. Forms.Button();
        this.WithoutThr eadButton = new System.Windows. Forms.Button();
        this.Exit = new System.Windows. Forms.Button();
        this.statusStri p1.SuspendLayou t();
        this.SuspendLay out();
        //
        // Status
        //
        this.Status.Loc ation = new System.Drawing. Point(30, 12);
        this.Status.Mul tiline = true;
        this.Status.Nam e = "Status";
        this.Status.Siz e = new System.Drawing. Size(364, 286);
        this.Status.Tab Index = 0;
        //
        // statusStrip1
        //
        this.statusStri p1.Items.AddRan ge(new
        System.Windows. Forms.ToolStrip Item[] {
        this.toolStripS tatusLabel1});
        this.statusStri p1.Location = new System.Drawing. Point(0, 347);
        this.statusStri p1.Name = "statusStri p1";
        this.statusStri p1.Size = new System.Drawing. Size(495, 22);
        this.statusStri p1.TabIndex = 1;
        this.statusStri p1.Text = "statusStri p1";
        //
        // toolStripStatus Label1
        //
        this.toolStripS tatusLabel1.Nam e = "toolStripStatu sLabel1";
        this.toolStripS tatusLabel1.Siz e = new System.Drawing. Size(0,
        17);
        //
        // WithThreadButto n
        //
        this.WithThread Button.Location = new System.Drawing. Point(187,
        316);
        this.WithThread Button.Name = "WithThreadButt on";
        this.WithThread Button.Size = new System.Drawing. Size(90, 23);
        this.WithThread Button.TabIndex = 2;
        this.WithThread Button.Text = "With Thread";
        this.WithThread Button.UseVisua lStyleBackColor = true;
        this.WithThread Button.Click += new
        System.EventHan dler(this.WithT hreadButton_Cli ck);
        //
        // WithoutThreadBu tton
        //
        this.WithoutThr eadButton.Locat ion = new System.Drawing. Point(30,
        316);
        this.WithoutThr eadButton.Name = "WithoutThreadB utton";
        this.WithoutThr eadButton.Size = new System.Drawing. Size(114,
        23);
        this.WithoutThr eadButton.TabIn dex = 3;
        this.WithoutThr eadButton.Text = "Without Thread";
        this.WithoutThr eadButton.UseVi sualStyleBackCo lor = true;
        this.WithoutThr eadButton.Click += new
        System.EventHan dler(this.Witho utThreadButton_ Click);
        //
        // Exit
        //
        this.Exit.Locat ion = new System.Drawing. Point(318, 316);
        this.Exit.Name = "Exit";
        this.Exit.Size = new System.Drawing. Size(75, 23);
        this.Exit.TabIn dex = 4;
        this.Exit.Text = "Exit";
        this.Exit.UseVi sualStyleBackCo lor = true;
        this.Exit.Click += new System.EventHan dler(this.Exit_ Click);
        //
        // Form1
        //
        this.AutoScaleD imensions = new System.Drawing. SizeF(6F, 13F);
        this.AutoScaleM ode = System.Windows. Forms.AutoScale Mode.Font;
        this.ClientSize = new System.Drawing. Size(495, 369);
        this.Controls.A dd(this.Exit);
        this.Controls.A dd(this.Without ThreadButton);
        this.Controls.A dd(this.WithThr eadButton);
        this.Controls.A dd(this.statusS trip1);
        this.Controls.A dd(this.Status) ;
        this.Name = "Form1";
        this.Text = "Form1";
        this.Load += new System.EventHan dler(this.Form1 _Load);
        this.statusStri p1.ResumeLayout (false);
        this.statusStri p1.PerformLayou t();
        this.ResumeLayo ut(false);
        this.PerformLay out();

        }

        #endregion

        private System.Windows. Forms.TextBox Status;
        private System.Windows. Forms.StatusStr ip statusStrip1;
        private System.Windows. Forms.ToolStrip StatusLabel
        toolStripStatus Label1;
        private System.Windows. Forms.ToolStrip StatusLabel
        toolStripStatus Label2;
        private System.Windows. Forms.Button WithThreadButto n;
        private System.Windows. Forms.Button WithoutThreadBu tton;
        private System.Windows. Forms.Button Exit;
        }
        }
        *************** *************** *************** *************** **

        Not sure why there are 2 "partial class form1" classes.

        Thanks,

        Tom


        Comment

        • Peter Duniho

          #5
          Re: Set up Display on status line with Threading

          On Sat, 11 Oct 2008 20:51:06 -0700, tshad <tfs@dslextreme .comwrote:
          [...]
          Cross-thread operation not valid: Control 'Status' accessed from a
          thread other than the thread it was created on.
          >
          but I don't get the error when setting the toolStripStatus Label from the
          Maintenance function:
          >
          display.StatusB ar = "Now Processing... " + file;
          >
          Why is that? They are both using the "this" that was passed.
          The cross-thread exception doesn't have anything to do with what objects
          or methods are used per se. The same method accessing the same object
          would not throw the exception if executed on one thread (the thread that
          owns the object), and yet would throw the exception if executed on a
          different thread.
          Just trying to understand the different ways to do this so I can choose
          the
          right way in other situations as well.
          I'm sorry. Other than the above that I commented on, I didn't see
          anything appreciably different in your most recent post as compared to the
          previous one, except for the code. I did make an attempt to answer the
          question; did you consider that answer at all? If you did and it wasn't
          applicable, you should explain why. If you didn't, then you should.

          Pete

          Comment

          • tshad

            #6
            Re: Set up Display on status line with Threading


            "Peter Duniho" <NpOeStPeAdM@nn owslpianmk.comw rote in message
            news:op.uiv8utp c8jd0ej@petes-computer.local. ..
            On Sat, 11 Oct 2008 20:51:06 -0700, tshad <tfs@dslextreme .comwrote:
            >
            >[...]
            > Cross-thread operation not valid: Control 'Status' accessed from a
            >thread other than the thread it was created on.
            >>
            >but I don't get the error when setting the toolStripStatus Label from the
            >Maintenance function:
            >>
            > display.StatusB ar = "Now Processing... " + file;
            >>
            >Why is that? They are both using the "this" that was passed.
            >
            The cross-thread exception doesn't have anything to do with what objects
            or methods are used per se. The same method accessing the same object
            would not throw the exception if executed on one thread (the thread that
            owns the object), and yet would throw the exception if executed on a
            different thread.
            >
            >Just trying to understand the different ways to do this so I can choose
            >the
            >right way in other situations as well.
            >
            I'm sorry. Other than the above that I commented on, I didn't see
            anything appreciably different in your most recent post as compared to the
            previous one, except for the code. I did make an attempt to answer the
            question; did you consider that answer at all? If you did and it wasn't
            applicable, you should explain why. If you didn't, then you should.
            >
            I sent the example because you said it would help if you had a better
            example: "Without a concise-but-complete code sample to work with, it's
            difficult to propose a precise change for your particular scenario.

            I did try your example, but got a couple of errors on the get:

            Since 'System.Windows .Forms.MethodIn voker' returns void, a return keyword
            must not be followed by an object expression

            Cannot convert anonymous method to delegate type
            'System.Windows .Forms.MethodIn voker' because some of the return types in the
            block are not implicitly convertible to the delegate return type

            I also got a semicolon error on the Set. Not sure why, it looks correct.
            It expects a semicolon before the last parenthesis.

            string IStatusDisplay. Status
            {
            get
            {
            return (string)Status. Invoke((MethodI nvoker)delegate {
            return Status.Text; });
            //return Status.Text;
            }
            set
            {
            Status.Invoke(( MethodInvoker)d elegate { Status.Text =
            value });
            //Status.Text = value;
            }
            }

            Thanks,

            Tom
            Pete

            Comment

            • tshad

              #7
              Re: Set up Display on status line with Threading

              JTC^..^ wrote:
              On 11 Oct, 06:23, "tshad" <t...@dslextrem e.comwrote:
              >I have a Windows App that is doing some work and then writing a "Now
              >Processing.. ." line to the status line of the window as well as the
              >Textbox on the form.
              >>
              >But the problem is that the work is in another class from the main
              >class. So it couldn't access the Status Line or textbox.
              >>
              >So what we did was set them up as properties:
              >>
              >string IStatusDisplay. Status
              >{
              >get
              >{
              >return Status.Text;
              >}
              >set
              >{
              >Status.Text = value;
              >}
              >}
              >>
              >string IStatusDisplay. StatusBar
              >{
              >get
              >{
              >return toolStripStatus Label1.Text;
              >}
              >set
              >{
              >toolStripStatu sLabel1.Text = value;
              >this.Refresh() ;
              >}
              >}
              >>
              >Then in my code I would call it like:
              >>
              >Maintenance.Ch eckAll(this);
              >>
              >And the function is:
              >>
              >public static void CheckAll(IStatu sDisplay display)
              >{
              >...
              >display.Status Bar = "Now Processing... " +
              >Path.GetFileNa me(file);
              >>
              >display.Stat us += file + Environment.New Line;
              >>
              >}
              >>
              >This works fine until you try to set it up and call it from a thread
              >- for one thing you can't use the this.Refresh() because you get an
              >error:
              >>
              >this.Refresh() ;
              >>
              >Gets me this error:
              >>
              >Cross-thread operation not valid: Control 'FieldNameMapSe tup'
              >accessed from a thread other than the thread it was created on.
              >>
              >Here I am in another function doing a - "display.Status Bar". It is
              >executing the above property until it hits the "this" statement.
              >>
              >or if you access a button on the page like:
              >>
              >btnExit.Enable d = true;
              >>
              >I get the error:
              >Cross-thread operation not valid: Control 'btnExit' accessed
              >from a thread other than the thread it was created on.
              >>
              >I am trying to find out how to access the controls on the Form from
              >either the same class or a different class (which was why we were
              >passing "this" to the other class).
              >>
              >This all works fine until you put it in a thread.
              >>
              >Thanks,
              >>
              >Tom
              >
              As a solution to getting the status from one class to another use
              events. The event notifies the form (or any other classes using the
              class) of the status change. Call a method to trigger the event.. e.g.
              OnStatusChanged ()
              >
              Your class would contain an event something like this....
              >
              public event EventHandler StatusChanged;
              private void OnStatusChanged ()
              {
              EventHandler handler = StatusChanged;
              >
              if(handler != null)
              {
              EventArgs args = new EventArgs();
              handler(this, args);
              }
              }
              >
              Your form code will look something like this. Where you instantiate
              the class subscribe to the event.
              >
              ....
              MyClass class = new MyClass();
              class.StatusCha nged += new
              StatusChangedEv entHandler(clas s_StatusChanged EventHandler);
              ...
              }
              >
              private void class_StatusCha ngedEventHandle r(object sender, EventArgs
              e)
              {
              this.lblStatus. Text = ((MyClass)sende r).Status;
              }
              Not sure how I would do this.

              In my sample, that I sent to Peter, I have form1.cs where the objects reside
              (Status being a TextBox). So that the code looks something like:
              *************** *************** *********
              namespace ControlAccessAc rossClasses
              {
              public partial class Form1 : Form, IStatusDisplay
              {
              public Form1()
              {
              InitializeCompo nent();
              }

              public event EventHandler StatusChanged;
              private void OnStatusChanged ()
              {
              EventHandler handler = StatusChanged;

              if (handler != null)
              {
              EventArgs args = new EventArgs();
              handler(this, args);
              }
              }
              *************** *************** **

              Not sure where I would put the other code.

              Also, how does the other class from the thread access this control?

              Thanks,

              Tom


              Comment

              • Peter Duniho

                #8
                Re: Set up Display on status line with Threading

                On Sun, 12 Oct 2008 20:18:51 -0700, tshad <tfs@dslextreme .comwrote:
                [...]
                I did try your example, but got a couple of errors on the get:
                >
                Since 'System.Windows .Forms.MethodIn voker' returns void, a return keyword
                must not be followed by an object expression
                Sorry. That's my fault. Been operating on only half cylinders lately. :(

                Anyway, the error happens because I used the "MethodInvo ker" delegate type
                for an anonymous method that returns a value. The signatures don't match.

                If you're using .NET 3.5, try "Func<strin g>" instead of "MethodInvoker" .
                [...]
                I also got a semicolon error on the Set. Not sure why, it looks correct.
                It expects a semicolon before the last parenthesis.
                You are missing a semi-colon after the word "value". Also my fault.

                I should have warned you that I hadn't actually compiled the code I
                posted. That said, you should practice the techniques more so that you're
                able to fix little mistakes like that yourself in the future. :)

                Pete

                Comment

                • tshad

                  #9
                  Re: Set up Display on status line with Threading


                  "Peter Duniho" <NpOeStPeAdM@nn owslpianmk.comw rote in message
                  news:op.uix3rkh 68jd0ej@petes-computer.local. ..
                  On Sun, 12 Oct 2008 20:18:51 -0700, tshad <tfs@dslextreme .comwrote:
                  >
                  >[...]
                  >I did try your example, but got a couple of errors on the get:
                  >>
                  >Since 'System.Windows .Forms.MethodIn voker' returns void, a return keyword
                  >must not be followed by an object expression
                  >
                  Sorry. That's my fault. Been operating on only half cylinders lately.
                  :(
                  >
                  Anyway, the error happens because I used the "MethodInvo ker" delegate type
                  for an anonymous method that returns a value. The signatures don't match.
                  >
                  If you're using .NET 3.5, try "Func<strin g>" instead of "MethodInvoker" .
                  Actually, I am using VS 2005 for the actual program.
                  >
                  >[...]
                  >I also got a semicolon error on the Set. Not sure why, it looks correct.
                  >It expects a semicolon before the last parenthesis.
                  >
                  You are missing a semi-colon after the word "value". Also my fault.
                  >
                  I should have warned you that I hadn't actually compiled the code I
                  posted. That said, you should practice the techniques more so that you're
                  able to fix little mistakes like that yourself in the future. :)
                  That is what I am doing.

                  Trying to look at the different options to get a better handle on when and
                  where to use each.

                  Thanks,

                  Tom
                  >
                  Pete

                  Comment

                  • Peter Duniho

                    #10
                    Re: Set up Display on status line with Threading

                    On Sun, 12 Oct 2008 22:30:10 -0700, tshad <tfs@dslextreme .comwrote:
                    >If you're using .NET 3.5, try "Func<strin g>" instead of "MethodInvoker" .
                    >
                    Actually, I am using VS 2005 for the actual program.
                    Okay. Well, you can declare the Func<Tdelegate yourself:

                    delegate T Func<T>();

                    Or just declare a non-generic delegate for that specific use:

                    delegate string StringFunc();

                    Pete

                    Comment

                    Working...