Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / C# / November 2007

Tip: Looking for answers? Try searching our database.

Threading and Instances

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Trecius - 30 Nov 2007 15:26 GMT
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[i].val);
   }
 }

 public void ThreadFunc()
 {
   Random r = new Random();
   for (int i = 0; i < this.m_list.Count; 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 - 30 Nov 2007 15:34 GMT
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
Marc Gravell - 30 Nov 2007 15:38 GMT
And can I point out that I already told you this?

http://groups.google.co.uk/group/microsoft.public.dotnet.languages.csharp/browse
_thread/thread/6479abc1c12a8bba


Marc
Trecius - 30 Nov 2007 15:41 GMT
Mr. Gravell:

So should my struct be a class?

Trecius

> 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.
[quoted text clipped - 16 lines]
>
> Marc
Bill Butler - 30 Nov 2007 16:15 GMT
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

> Mr. Gravell:
>
[quoted text clipped - 23 lines]
>>
>> Marc
Ignacio Machin ( .NET/ C# MVP ) - 30 Nov 2007 15:42 GMT
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

Signature

Ignacio Machin
http://www.laceupsolutions.com
Mobile & warehouse Solutions.

> Hello, Newsgroupians:
>
[quoted text clipped - 78 lines]
>
> Trecius
Rene - 30 Nov 2007 20:06 GMT
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?

> Hello, Newsgroupians:
>
[quoted text clipped - 78 lines]
>
> Trecius

Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.