Threading and Instances

T

Trecius

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<MyPoint> m_list = 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(this.ThreadFunc));
th.Start();
while (th.IsAlive) // Wait until the secondary thread is done
{
Thread.Sleep(1000);
}

for (int i = 0; i < m_list.Count; i++)
{
Console.WriteLine(m_list.val);
}
}

public void ThreadFunc()
{
Random r = new Random();
for (int i = 0; i < this.m_list.Count; i++)
{
MyPoint pt = this.m_list;
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
 
M

Marc Gravell

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(1000);
}


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

Marc
 
I

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

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
 
B

Bill Butler

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
 
R

Rene

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?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top