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

  • Default (No Skin)
  • No Skin
Collapse
Code Project
CODE PROJECT For Those Who Code
  • Home
  • Articles
  • FAQ
Community
  1. Home
  2. General Programming
  3. C#
  4. Communicating with a Thread

Communicating with a Thread

Scheduled Pinned Locked Moved C#
questioncsharpc++helptutorial
13 Posts 4 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.
  • D Offline
    D Offline
    Demian Panello
    wrote on last edited by
    #1

    Hi!. I wrote an application that start a thread that read some data from the communication port. The problem is that I want to put the data in a textbox, (text1), and I don't know how to do that:confused:. In C++ I just use a global variable, but how can I define a global variable in Visual C#. How can I get data from the thread?. Thank you very much. Demian.

    J H 2 Replies Last reply
    0
    • D Demian Panello

      Hi!. I wrote an application that start a thread that read some data from the communication port. The problem is that I want to put the data in a textbox, (text1), and I don't know how to do that:confused:. In C++ I just use a global variable, but how can I define a global variable in Visual C#. How can I get data from the thread?. Thank you very much. Demian.

      J Offline
      J Offline
      Judah Gabriel Himango
      wrote on last edited by
      #2

      Global variables are looked down upon in the object-oriented world, and are not allowed in Java or C#. If you want to place text inside the textbox, just pass your textbox instance to the object reading your communication port. Also note that Windows Forms controls are single threaded in nature; it's a no-no to modify them from a thread other than the thread that owns the handle to the control (ie the thread that the control was created on). Fortunately for you and I, all Windows Forms controls contain a method called .Invoke that lets you call a method on the control using the thread that owns the handle. --------------------------- He who knows that enough is enough will always have enough. -Lao Tsu

      S 1 Reply Last reply
      0
      • D Demian Panello

        Hi!. I wrote an application that start a thread that read some data from the communication port. The problem is that I want to put the data in a textbox, (text1), and I don't know how to do that:confused:. In C++ I just use a global variable, but how can I define a global variable in Visual C#. How can I get data from the thread?. Thank you very much. Demian.

        H Offline
        H Offline
        Heath Stewart
        wrote on last edited by
        #3

        Use Control.InvokeRequired and Control.Invoke from threads other than the thread on which the control was created. Global variables are also not a very good way unless you use good locking when reading/writing from/to them (the lock keyword in C# is a simple way to do this using a monitor). To use a global variable, you can always use a static property or, if your threaded method is a method defined on the Control class that contains your TextBox, just use a private variable (and be sure to lock it). To write to the text box, make sure your thread class or procedure has a reference to your TextBox (for example, you could thread a single method in your class which contains the TextBox reference). If you're not sure if your method would be threaded or not, use the code below (otherwise eliminate the check for Control.InvokeRequired):

        private void ReadFromPort()
        {
        string value = value from port;
        if (text1.InvokeRequired)
        {
        // This isn't really optimized, but it's only an example...
        Type t = text1.GetType();
        MethodInfo info = t.GetProperty("Text").GetSetMethod();
        Delegate d = Delegate.CreateDelegate(t, info);
        text1.Invoke(d, new object[] {value});
        }
        else text1.Text = value;
        }

        Microsoft MVP, Visual C# My Articles

        J 1 Reply Last reply
        0
        • J Judah Gabriel Himango

          Global variables are looked down upon in the object-oriented world, and are not allowed in Java or C#. If you want to place text inside the textbox, just pass your textbox instance to the object reading your communication port. Also note that Windows Forms controls are single threaded in nature; it's a no-no to modify them from a thread other than the thread that owns the handle to the control (ie the thread that the control was created on). Fortunately for you and I, all Windows Forms controls contain a method called .Invoke that lets you call a method on the control using the thread that owns the handle. --------------------------- He who knows that enough is enough will always have enough. -Lao Tsu

          S Offline
          S Offline
          SapiensBwG
          wrote on last edited by
          #4

          sorry judah didnt get that last part! could u exemplify! thx in advance i was needing this for another app

          J 1 Reply Last reply
          0
          • S SapiensBwG

            sorry judah didnt get that last part! could u exemplify! thx in advance i was needing this for another app

            J Offline
            J Offline
            Judah Gabriel Himango
            wrote on last edited by
            #5

            See Heath's post below. --------------------------- He who knows that enough is enough will always have enough. -Lao Tsu

            1 Reply Last reply
            0
            • H Heath Stewart

              Use Control.InvokeRequired and Control.Invoke from threads other than the thread on which the control was created. Global variables are also not a very good way unless you use good locking when reading/writing from/to them (the lock keyword in C# is a simple way to do this using a monitor). To use a global variable, you can always use a static property or, if your threaded method is a method defined on the Control class that contains your TextBox, just use a private variable (and be sure to lock it). To write to the text box, make sure your thread class or procedure has a reference to your TextBox (for example, you could thread a single method in your class which contains the TextBox reference). If you're not sure if your method would be threaded or not, use the code below (otherwise eliminate the check for Control.InvokeRequired):

              private void ReadFromPort()
              {
              string value = value from port;
              if (text1.InvokeRequired)
              {
              // This isn't really optimized, but it's only an example...
              Type t = text1.GetType();
              MethodInfo info = t.GetProperty("Text").GetSetMethod();
              Delegate d = Delegate.CreateDelegate(t, info);
              text1.Invoke(d, new object[] {value});
              }
              else text1.Text = value;
              }

              Microsoft MVP, Visual C# My Articles

              J Offline
              J Offline
              Judah Gabriel Himango
              wrote on last edited by
              #6

              Keeping in mind that was example code, FYI that snippet won't work; Delegate.CreateDelegate takes a Type parameter for delegate types only. You might want to try this instead:

              private delegate void SetTextDelegate(TextBox tb, string text);

              private void ReadFromPort(TextBox tb)
              {
              string portData = ... // read from communications port

                 this.SetText(tb, portData);
              

              }

              private void SetText(TextBox tb, string text)
              {
              if(tb.InvokeRequired) // if we're calling from any thread other than the one used to create the text box
              {
              tb.Invoke(new SetTextDelegate(SetText), new object[] {tb, text});
              }
              else tb.Text = text; // no invoke required
              }

              I *think* that should work. :) --------------------------- He who knows that enough is enough will always have enough. -Lao Tsu

              S D 3 Replies Last reply
              0
              • J Judah Gabriel Himango

                Keeping in mind that was example code, FYI that snippet won't work; Delegate.CreateDelegate takes a Type parameter for delegate types only. You might want to try this instead:

                private delegate void SetTextDelegate(TextBox tb, string text);

                private void ReadFromPort(TextBox tb)
                {
                string portData = ... // read from communications port

                   this.SetText(tb, portData);
                

                }

                private void SetText(TextBox tb, string text)
                {
                if(tb.InvokeRequired) // if we're calling from any thread other than the one used to create the text box
                {
                tb.Invoke(new SetTextDelegate(SetText), new object[] {tb, text});
                }
                else tb.Text = text; // no invoke required
                }

                I *think* that should work. :) --------------------------- He who knows that enough is enough will always have enough. -Lao Tsu

                S Offline
                S Offline
                SapiensBwG
                wrote on last edited by
                #7

                thx for the help guys appreciate it

                1 Reply Last reply
                0
                • J Judah Gabriel Himango

                  Keeping in mind that was example code, FYI that snippet won't work; Delegate.CreateDelegate takes a Type parameter for delegate types only. You might want to try this instead:

                  private delegate void SetTextDelegate(TextBox tb, string text);

                  private void ReadFromPort(TextBox tb)
                  {
                  string portData = ... // read from communications port

                     this.SetText(tb, portData);
                  

                  }

                  private void SetText(TextBox tb, string text)
                  {
                  if(tb.InvokeRequired) // if we're calling from any thread other than the one used to create the text box
                  {
                  tb.Invoke(new SetTextDelegate(SetText), new object[] {tb, text});
                  }
                  else tb.Text = text; // no invoke required
                  }

                  I *think* that should work. :) --------------------------- He who knows that enough is enough will always have enough. -Lao Tsu

                  D Offline
                  D Offline
                  Demian Panello
                  wrote on last edited by
                  #8

                  Hi Lao. Thank you for you help. But, the thread method is the method that read the comm. port, so can I pass a parameter to it?, a parameter like TextBox tb?. That method is in another class, no in the class that holds the textbox, and should I pass every control as parameter that I want to write, (with data from the comm port)?. Thank you again for your time. Demian.

                  1 Reply Last reply
                  0
                  • J Judah Gabriel Himango

                    Keeping in mind that was example code, FYI that snippet won't work; Delegate.CreateDelegate takes a Type parameter for delegate types only. You might want to try this instead:

                    private delegate void SetTextDelegate(TextBox tb, string text);

                    private void ReadFromPort(TextBox tb)
                    {
                    string portData = ... // read from communications port

                       this.SetText(tb, portData);
                    

                    }

                    private void SetText(TextBox tb, string text)
                    {
                    if(tb.InvokeRequired) // if we're calling from any thread other than the one used to create the text box
                    {
                    tb.Invoke(new SetTextDelegate(SetText), new object[] {tb, text});
                    }
                    else tb.Text = text; // no invoke required
                    }

                    I *think* that should work. :) --------------------------- He who knows that enough is enough will always have enough. -Lao Tsu

                    D Offline
                    D Offline
                    Demian Panello
                    wrote on last edited by
                    #9

                    The code works fine. But I must pass a textbox reference to the class constructor. And this is a very particular case, 'cause I don't know how many controls I will have, to show the data that the thread read from the comm port. Thank you Judah. Demian.

                    H 1 Reply Last reply
                    0
                    • D Demian Panello

                      The code works fine. But I must pass a textbox reference to the class constructor. And this is a very particular case, 'cause I don't know how many controls I will have, to show the data that the thread read from the comm port. Thank you Judah. Demian.

                      H Offline
                      H Offline
                      Heath Stewart
                      wrote on last edited by
                      #10

                      This is only if your thread method is in a different class. More than likely, there's no need to do that. In both Judah's and my examples, we assumed the method that will be invoked in another thread was part of the same class, so it already has a reference to the TextBox. This is preferred unless you have some good reason for changing it. If you do, then create a new instance of another class - passing the TextBox reference into the constructor - and start a thread on a method of that class. This is unnecessary, though, because you're creating another class just to run a method in another thread? Why go to the trouble if you don't have to.

                      Microsoft MVP, Visual C# My Articles

                      D 1 Reply Last reply
                      0
                      • H Heath Stewart

                        This is only if your thread method is in a different class. More than likely, there's no need to do that. In both Judah's and my examples, we assumed the method that will be invoked in another thread was part of the same class, so it already has a reference to the TextBox. This is preferred unless you have some good reason for changing it. If you do, then create a new instance of another class - passing the TextBox reference into the constructor - and start a thread on a method of that class. This is unnecessary, though, because you're creating another class just to run a method in another thread? Why go to the trouble if you don't have to.

                        Microsoft MVP, Visual C# My Articles

                        D Offline
                        D Offline
                        Demian Panello
                        wrote on last edited by
                        #11

                        Hi! Well, I have a class hierarchy, and theses classes must keep a communication "alive" with a devices pluged in the comm port. The device, if it has no heceived a command stop the communication. That is the trouble, the thread method is a method deep int the hierarchy. Thank you for your time. Demian.

                        H 1 Reply Last reply
                        0
                        • D Demian Panello

                          Hi! Well, I have a class hierarchy, and theses classes must keep a communication "alive" with a devices pluged in the comm port. The device, if it has no heceived a command stop the communication. That is the trouble, the thread method is a method deep int the hierarchy. Thank you for your time. Demian.

                          H Offline
                          H Offline
                          Heath Stewart
                          wrote on last edited by
                          #12

                          Like I said, then, either pass the TextBox reference into the class's constructor or set a property before you start the thread on a method of that class.

                          Microsoft MVP, Visual C# My Articles

                          D 1 Reply Last reply
                          0
                          • H Heath Stewart

                            Like I said, then, either pass the TextBox reference into the class's constructor or set a property before you start the thread on a method of that class.

                            Microsoft MVP, Visual C# My Articles

                            D Offline
                            D Offline
                            Demian Panello
                            wrote on last edited by
                            #13

                            Hi. Yes, that works, but there's no relation between the classes hierarchy and a control as reference in a constructor or in a property. Theses are communication protocol classes, it's so weird to find a control reference in their definitions. I loss the essence of the class hierarchy just putting a textbox in the definitions. That's the problem. Thank you very much for your feedback. Demian.

                            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