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

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Writing to ListBox from multiple threads

Writing to ListBox from multiple threads

Scheduled Pinned Locked Moved C#
15 Posts 5 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • H Henry Minute

    Hi Bruce, I think that the problem might be with the: if (InvokeRequired) line. Try: if (this.lb.InvokeRequired) and then lb.BeginInvoke(new LogDelegate(log), new object[] { message }); Hope this helps. :)

    Henry Minute Do not read medical books! You could die of a misprint. - Mark Twain Girl: (staring) "Why do you need an icy cucumber?" “I want to report a fraud. The government is lying to us all.”

    N Offline
    N Offline
    Nicholas Butler
    wrote on last edited by
    #6

    The Form and ListBox both run on the same ( UI ) thread, so it doesn't matter which you use. Nick

    ---------------------------------- Be excellent to each other :)

    H 1 Reply Last reply
    0
    • H Henry Minute

      Hi Bruce, I think that the problem might be with the: if (InvokeRequired) line. Try: if (this.lb.InvokeRequired) and then lb.BeginInvoke(new LogDelegate(log), new object[] { message }); Hope this helps. :)

      Henry Minute Do not read medical books! You could die of a misprint. - Mark Twain Girl: (staring) "Why do you need an icy cucumber?" “I want to report a fraud. The government is lying to us all.”

      B Offline
      B Offline
      Bruce Coward
      wrote on last edited by
      #7

      Thanks Henry. That is still throwing compile errors. I am beginning to suspect that the problem is because the two background threads are each in their own class file and that they cannot see the log(message) method in Form1 unless I make that method a static. Having made it a static the compiler is having trouble with pretty much every line of the method as follows: Error 2 An object reference is required for the non-static field, method, or property 'System.Windows.Forms.Control.Invoke(System.Delegate, params object[])' \\Server1\srvr\Code\PC Programs\SYSTest\SYSTest\Form1.cs 60 17 SYSTest Can anybody confirm whether I can make the log(message) a static or do I have to restructure my solution to put the background threads inside the Form1 class so I do not have to make the function into a static? Many thanks for all your valuable input, Bruce

      H 1 Reply Last reply
      0
      • N Nicholas Butler

        The Form and ListBox both run on the same ( UI ) thread, so it doesn't matter which you use. Nick

        ---------------------------------- Be excellent to each other :)

        H Offline
        H Offline
        Henry Minute
        wrote on last edited by
        #8

        Yes, of course! How dumb. :-O

        Henry Minute Do not read medical books! You could die of a misprint. - Mark Twain Girl: (staring) "Why do you need an icy cucumber?" “I want to report a fraud. The government is lying to us all.”

        1 Reply Last reply
        0
        • B Bruce Coward

          Thanks Henry. That is still throwing compile errors. I am beginning to suspect that the problem is because the two background threads are each in their own class file and that they cannot see the log(message) method in Form1 unless I make that method a static. Having made it a static the compiler is having trouble with pretty much every line of the method as follows: Error 2 An object reference is required for the non-static field, method, or property 'System.Windows.Forms.Control.Invoke(System.Delegate, params object[])' \\Server1\srvr\Code\PC Programs\SYSTest\SYSTest\Form1.cs 60 17 SYSTest Can anybody confirm whether I can make the log(message) a static or do I have to restructure my solution to put the background threads inside the Form1 class so I do not have to make the function into a static? Many thanks for all your valuable input, Bruce

          H Offline
          H Offline
          Henry Minute
          wrote on last edited by
          #9

          The two background threads certainly need to be able to 'see' Form1, the best bet is probably as Nick suggested by passing a reference to Form1 in the constructor of the threads. The problems caused by making log() static are that log() itself will not be able to see the listbox.

          Henry Minute Do not read medical books! You could die of a misprint. - Mark Twain Girl: (staring) "Why do you need an icy cucumber?" “I want to report a fraud. The government is lying to us all.”

          B 1 Reply Last reply
          0
          • H Henry Minute

            The two background threads certainly need to be able to 'see' Form1, the best bet is probably as Nick suggested by passing a reference to Form1 in the constructor of the threads. The problems caused by making log() static are that log() itself will not be able to see the listbox.

            Henry Minute Do not read medical books! You could die of a misprint. - Mark Twain Girl: (staring) "Why do you need an icy cucumber?" “I want to report a fraud. The government is lying to us all.”

            B Offline
            B Offline
            Bruce Coward
            wrote on last edited by
            #10

            "The problems caused by making log() static are that log() itself will not be able to see the listbox." That makes sense. The compiler errors when the method is static could very well be caused by that. I will try Nick's suggestion and let you know. Many, many thanks Bruce

            1 Reply Last reply
            0
            • B Bruce Coward

              I have a fairly standard Form1.cs with a listbox to display comms traffic. The comms traffic comes from two different interfaces each of which is handled by it's own background thread. I want to log the traffic in the listbox on Form1 and have set up a delegate / Invoke routine as below in the Form1 class:

                  //\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
                  // public void log(string message)
                  // This function appends the message to the list box
                  //\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
                  public delegate void LogDelegate(string s);
                  public void log(string message)
                  {
                      if (InvokeRequired)
                      {
                          Invoke(new LogDelegate(log), new object\[\] { message });
                      }
                      else
                      {
                          lb.Items.Add(message);
                          lb.TopIndex = lb.Items.Count - 1;
                      }
                  } // End of void log()
              

              When I try to call log(string) from either of the backgound threads the compiler isn't finding this function and I cant for the life of me see why not. I did try making it a static but that threw lots of errors so I took that away. What am I doing wrong please? Many thanks, Bruce :confused:

              D Offline
              D Offline
              DaveyM69
              wrote on last edited by
              #11

              What is spawning the threads? If it's the same class then you shouldn't be having an issue. If it's a seperate class then the easiest way is to raise an event in that class, that the form can subscribe to, and in the handler invoke the method required.

              Dave
              BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)
              Visual Basic is not used by normal people so we're not covering it here. (Uncyclopedia)
              Why are you using VB6? Do you hate yourself? (Christian Graus)

              1 Reply Last reply
              0
              • B Bruce Coward

                Hi Nick, Thanks for your response. The thread will see Form1.log() if I make the log method a static. However if I make it a static the compiler kicks on just about every line of log() with "Object refernece required for ..." I just am not sure what it is looking for that I haven't provided. Cheers, Bruce

                L Offline
                L Offline
                Luc Pattyn
                wrote on last edited by
                #12

                Yep, that is why Nick said myForm1.log, not Form1.log. myForm1 should be a variable pointing to your Form1 instance. :)

                Luc Pattyn [Forum Guidelines] [My Articles]


                - before you ask a question here, search CodeProject, then Google - the quality and detail of your question reflects on the effectiveness of the help you are likely to get - use the code block button (PRE tags) to preserve formatting when showing multi-line code snippets


                1 Reply Last reply
                0
                • B Bruce Coward

                  I have a fairly standard Form1.cs with a listbox to display comms traffic. The comms traffic comes from two different interfaces each of which is handled by it's own background thread. I want to log the traffic in the listbox on Form1 and have set up a delegate / Invoke routine as below in the Form1 class:

                      //\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
                      // public void log(string message)
                      // This function appends the message to the list box
                      //\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
                      public delegate void LogDelegate(string s);
                      public void log(string message)
                      {
                          if (InvokeRequired)
                          {
                              Invoke(new LogDelegate(log), new object\[\] { message });
                          }
                          else
                          {
                              lb.Items.Add(message);
                              lb.TopIndex = lb.Items.Count - 1;
                          }
                      } // End of void log()
                  

                  When I try to call log(string) from either of the backgound threads the compiler isn't finding this function and I cant for the life of me see why not. I did try making it a static but that threw lots of errors so I took that away. What am I doing wrong please? Many thanks, Bruce :confused:

                  L Offline
                  L Offline
                  Luc Pattyn
                  wrote on last edited by
                  #13

                  Hi Bruce, the code shown is perfect. However the problem is elsewhere. You have to help those threads to find and use your log method. Especially for logging purposes I tend to do that with static events, like so (incomplete and unchecked code):

                  class Form1 : Form {
                  public Form() {
                  ...
                  Class2.Logger+=log; // one statement per "log client" class
                  }

                  public void log(string s) {...}
                  

                  }

                  and the "log clients" look like this:

                  class Class2 {
                  public static event Action<string> Logger;
                  private void log(string s) {
                  if (Logger!=null) Logger(s);
                  }
                  }

                  BTW: the event does not have to be static, but it allows for doing Logger+=log before the actual client objects have been created. PS: I always like to have a log(Exception) method too; I either solve that by doing the above stuff twice, or by adding the following code in every log client class:

                  private void log(Exception exc) {
                  foreach(string s in exc.ToString().Split('\r','\n')) if (s.Length!=0) log(s);
                  }

                  :)

                  Luc Pattyn [Forum Guidelines] [My Articles]


                  - before you ask a question here, search CodeProject, then Google - the quality and detail of your question reflects on the effectiveness of the help you are likely to get - use the code block button (PRE tags) to preserve formatting when showing multi-line code snippets


                  D 1 Reply Last reply
                  0
                  • L Luc Pattyn

                    Hi Bruce, the code shown is perfect. However the problem is elsewhere. You have to help those threads to find and use your log method. Especially for logging purposes I tend to do that with static events, like so (incomplete and unchecked code):

                    class Form1 : Form {
                    public Form() {
                    ...
                    Class2.Logger+=log; // one statement per "log client" class
                    }

                    public void log(string s) {...}
                    

                    }

                    and the "log clients" look like this:

                    class Class2 {
                    public static event Action<string> Logger;
                    private void log(string s) {
                    if (Logger!=null) Logger(s);
                    }
                    }

                    BTW: the event does not have to be static, but it allows for doing Logger+=log before the actual client objects have been created. PS: I always like to have a log(Exception) method too; I either solve that by doing the above stuff twice, or by adding the following code in every log client class:

                    private void log(Exception exc) {
                    foreach(string s in exc.ToString().Split('\r','\n')) if (s.Length!=0) log(s);
                    }

                    :)

                    Luc Pattyn [Forum Guidelines] [My Articles]


                    - before you ask a question here, search CodeProject, then Google - the quality and detail of your question reflects on the effectiveness of the help you are likely to get - use the code block button (PRE tags) to preserve formatting when showing multi-line code snippets


                    D Offline
                    D Offline
                    DaveyM69
                    wrote on last edited by
                    #14

                    Don't want to hijack the thread but... I experimented briefly with static events a while ago and came across a slight issue of objects not getting disposed. Normally, if a ClassA instance subscribes to an event in a ClassB instance, when ClassB instance goes out of scope, it will allow ClassA instance to be disposed if there are no other references. With a static event in ClassB, that never happens of course and ClassA instance will continue to exist for the application's lifetime unless it explicitly unsubscribes from the static event. Worth bearing in mind as otherwise unexpected things can happen, as well as potential memory pressures.

                    Dave
                    BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)
                    Visual Basic is not used by normal people so we're not covering it here. (Uncyclopedia)
                    Why are you using VB6? Do you hate yourself? (Christian Graus)

                    L 1 Reply Last reply
                    0
                    • D DaveyM69

                      Don't want to hijack the thread but... I experimented briefly with static events a while ago and came across a slight issue of objects not getting disposed. Normally, if a ClassA instance subscribes to an event in a ClassB instance, when ClassB instance goes out of scope, it will allow ClassA instance to be disposed if there are no other references. With a static event in ClassB, that never happens of course and ClassA instance will continue to exist for the application's lifetime unless it explicitly unsubscribes from the static event. Worth bearing in mind as otherwise unexpected things can happen, as well as potential memory pressures.

                      Dave
                      BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)
                      Visual Basic is not used by normal people so we're not covering it here. (Uncyclopedia)
                      Why are you using VB6? Do you hate yourself? (Christian Graus)

                      L Offline
                      L Offline
                      Luc Pattyn
                      wrote on last edited by
                      #15

                      Hi Dave, IMO your remark is perfectly valid in general; however in this situation the form implementing the log functionality is assumed to be the main form, and to live for as long as the app is running. If not, one should consider implementing the log server in a separate class, or drop the statics. :)

                      Luc Pattyn [Forum Guidelines] [My Articles]


                      - before you ask a question here, search CodeProject, then Google - the quality and detail of your question reflects on the effectiveness of the help you are likely to get - use the code block button (PRE tags) to preserve formatting when showing multi-line code snippets


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


                      • Login

                      • Don't have an account? Register

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