Threading and Instances

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • =?Utf-8?B?VHJlY2l1cw==?=

    #1

    Threading and Instances

    Hello, Newsgroupians:

    I'm a little confused when it comes to threads in C#. Here's what I'm
    trying to do...

    I have a List<containing a set of MyPoint(s)...

    public struct MyPoint
    {
    int x;
    int y;
    int val;
    }

    class MyClass
    {
    List<MyPointm_l ist = new List<MyPoint>() ;
    ...
    }

    Now, in my main thread I'm going to populate the list. Assume the
    following...

    class MyClass
    {
    public MyClass()
    {
    for (int i = 0; i < 10; i++)
    {
    MyPoint pt = new MyPoint;
    pt.x = <Some X>
    pt.y = <Some Y>
    // pt.val is changed in the thread

    m_list.Add(pt);
    }
    }
    ...
    }

    Now, in the secondary thread, I am going to be changing .val
    For simplicity, assume I do the following...

    class MyClass
    {
    void SomeFunc()
    {
    Thread th = new Thread(new ThreadStart(thi s.ThreadFunc));
    th.Start();
    while (th.IsAlive) // Wait until the secondary thread is done
    {
    Thread.Sleep(10 00);
    }

    for (int i = 0; i < m_list.Count; i++)
    {
    Console.WriteLi ne(m_list[i].val);
    }
    }

    public void ThreadFunc()
    {
    Random r = new Random();
    for (int i = 0; i < this.m_list.Cou nt; i++)
    {
    MyPoint pt = this.m_list[i];
    pt.val = r.Next();
    }
    ...
    }
    }

    Yet, even after waiting for the secondary thread to end, the .val for each
    MyPoint in the List<is always zero. I don't understand why it isn't
    changing. I've tried setting some variables to static; this didn't work.

    Overall, what do I need to do to make it so the secondary thread can write
    to the values in the List<and have the main thread read these values once
    the thread has ended? Thank you.


    Trecius
  • Marc Gravell

    #2
    Re: Threading and Instances

    The answer is that MyPoint is a struct; it has value-type semantics.
    Every time you get it from the list you get a *different* copy.

    Aside: there isn't any locking, but you've guarded against this OK
    because the two threads don't run at the same time - but be aware that
    there are some register issues which might stop loops exiting -
    and .Join() would be more efficient anyway.

    But more importantly:

    th.Start();
    while (th.IsAlive) // Wait until the secondary thread is done
    {
    Thread.Sleep(10 00);
    }


    Why start a thread, just to wait for it to end... run the code
    directly ;-p

    Marc

    Comment

    • Marc Gravell

      #3
      Re: Threading and Instances

      And can I point out that I already told you this?



      Marc

      Comment

      • =?Utf-8?B?VHJlY2l1cw==?=

        #4
        Re: Threading and Instances

        Mr. Gravell:

        So should my struct be a class?


        Trecius

        "Marc Gravell" wrote:
        The answer is that MyPoint is a struct; it has value-type semantics.
        Every time you get it from the list you get a *different* copy.
        >
        Aside: there isn't any locking, but you've guarded against this OK
        because the two threads don't run at the same time - but be aware that
        there are some register issues which might stop loops exiting -
        and .Join() would be more efficient anyway.
        >
        But more importantly:
        >
        th.Start();
        while (th.IsAlive) // Wait until the secondary thread is done
        {
        Thread.Sleep(10 00);
        }
        >
        >
        Why start a thread, just to wait for it to end... run the code
        directly ;-p
        >
        Marc
        >

        Comment

        • Ignacio Machin \( .NET/ C# MVP \)

          #5
          Re: Threading and Instances

          Hi,


          Just change MyPoint from a struct to a class and run the test again.

          Take a look at Jon Skeet's comment regarding value vs reference types

          --
          Ignacio Machin
          The #1 Warehouse Management System & Direct Store Delivery Software (DSD) for QuickBooks & ERP Systems – LaceUp Solutions

          Mobile & warehouse Solutions.
          "Trecius" <Trecius@discus sions.microsoft .comwrote in message
          news:27C86931-D12B-4AB0-9FC9-7215380B3E87@mi crosoft.com...
          Hello, Newsgroupians:
          >
          I'm a little confused when it comes to threads in C#. Here's what I'm
          trying to do...
          >
          I have a List<containing a set of MyPoint(s)...
          >
          public struct MyPoint
          {
          int x;
          int y;
          int val;
          }
          >
          class MyClass
          {
          List<MyPointm_l ist = new List<MyPoint>() ;
          ...
          }
          >
          Now, in my main thread I'm going to populate the list. Assume the
          following...
          >
          class MyClass
          {
          public MyClass()
          {
          for (int i = 0; i < 10; i++)
          {
          MyPoint pt = new MyPoint;
          pt.x = <Some X>
          pt.y = <Some Y>
          // pt.val is changed in the thread
          >
          m_list.Add(pt);
          }
          }
          ...
          }
          >
          Now, in the secondary thread, I am going to be changing .val
          For simplicity, assume I do the following...
          >
          class MyClass
          {
          void SomeFunc()
          {
          Thread th = new Thread(new ThreadStart(thi s.ThreadFunc));
          th.Start();
          while (th.IsAlive) // Wait until the secondary thread is done
          {
          Thread.Sleep(10 00);
          }
          >
          for (int i = 0; i < m_list.Count; i++)
          {
          Console.WriteLi ne(m_list[i].val);
          }
          }
          >
          public void ThreadFunc()
          {
          Random r = new Random();
          for (int i = 0; i < this.m_list.Cou nt; i++)
          {
          MyPoint pt = this.m_list[i];
          pt.val = r.Next();
          }
          ...
          }
          }
          >
          Yet, even after waiting for the secondary thread to end, the .val for each
          MyPoint in the List<is always zero. I don't understand why it isn't
          changing. I've tried setting some variables to static; this didn't work.
          >
          Overall, what do I need to do to make it so the secondary thread can write
          to the values in the List<and have the main thread read these values
          once
          the thread has ended? Thank you.
          >
          >
          Trecius

          Comment

          • Bill Butler

            #6
            Re: Threading and Instances

            Yes,

            A good rule of thumb is to ALWAYS use classes in your design.
            structs are not the same as in C++.

            Make sure that you fully understand all of the subtle ramifications of
            using structs in your design before attempting to do so. Most of the
            time you will find that classes are a far better choice.

            Bill


            "Trecius" <Trecius@discus sions.microsoft .comwrote in message
            news:FB9D2586-9D75-4327-A7A8-01E0E06BEE2F@mi crosoft.com...
            Mr. Gravell:
            >
            So should my struct be a class?
            >
            >
            Trecius
            >
            "Marc Gravell" wrote:
            >
            >The answer is that MyPoint is a struct; it has value-type semantics.
            >Every time you get it from the list you get a *different* copy.
            >>
            >Aside: there isn't any locking, but you've guarded against this OK
            >because the two threads don't run at the same time - but be aware
            >that
            >there are some register issues which might stop loops exiting -
            >and .Join() would be more efficient anyway.
            >>
            >But more importantly:
            >>
            > th.Start();
            > while (th.IsAlive) // Wait until the secondary thread is done
            > {
            > Thread.Sleep(10 00);
            > }
            >>
            >>
            >Why start a thread, just to wait for it to end... run the code
            >directly ;-p
            >>
            >Marc
            >>

            Comment

            • Rene

              #7
              Re: Threading and Instances

              Since several people already answered the question, the other question would
              be, why won't the compiler issue a warning such as:

              The private field 'pt' is assigned but its value is never used.

              And then add the squiggly line underneath the variable to make this very
              obvious. This would be nice since people always run into scenarios like
              this.

              I mean, I realize that the "ThreadFunc ()" function has the "pt.val =
              r.Next()" line that uses the 'pt' variable but there is only assignments to
              it right? the "ThreadFunc ()" never really extracts a value from 'pt' so my
              guess is that the warning would hold true.

              No? Yes? Maybe?




              "Trecius" <Trecius@discus sions.microsoft .comwrote in message
              news:27C86931-D12B-4AB0-9FC9-7215380B3E87@mi crosoft.com...
              Hello, Newsgroupians:
              >
              I'm a little confused when it comes to threads in C#. Here's what I'm
              trying to do...
              >
              I have a List<containing a set of MyPoint(s)...
              >
              public struct MyPoint
              {
              int x;
              int y;
              int val;
              }
              >
              class MyClass
              {
              List<MyPointm_l ist = new List<MyPoint>() ;
              ...
              }
              >
              Now, in my main thread I'm going to populate the list. Assume the
              following...
              >
              class MyClass
              {
              public MyClass()
              {
              for (int i = 0; i < 10; i++)
              {
              MyPoint pt = new MyPoint;
              pt.x = <Some X>
              pt.y = <Some Y>
              // pt.val is changed in the thread
              >
              m_list.Add(pt);
              }
              }
              ...
              }
              >
              Now, in the secondary thread, I am going to be changing .val
              For simplicity, assume I do the following...
              >
              class MyClass
              {
              void SomeFunc()
              {
              Thread th = new Thread(new ThreadStart(thi s.ThreadFunc));
              th.Start();
              while (th.IsAlive) // Wait until the secondary thread is done
              {
              Thread.Sleep(10 00);
              }
              >
              for (int i = 0; i < m_list.Count; i++)
              {
              Console.WriteLi ne(m_list[i].val);
              }
              }
              >
              public void ThreadFunc()
              {
              Random r = new Random();
              for (int i = 0; i < this.m_list.Cou nt; i++)
              {
              MyPoint pt = this.m_list[i];
              pt.val = r.Next();
              }
              ...
              }
              }
              >
              Yet, even after waiting for the secondary thread to end, the .val for each
              MyPoint in the List<is always zero. I don't understand why it isn't
              changing. I've tried setting some variables to static; this didn't work.
              >
              Overall, what do I need to do to make it so the secondary thread can write
              to the values in the List<and have the main thread read these values
              once
              the thread has ended? Thank you.
              >
              >
              Trecius

              Comment

              Working...