C# access class members from thread - c#

I'm trying to teach myself about threads in C#, and I've run into a problem. Lets say that this is my code:
class MyClass
{
public Queue variable;
internal MyClass()
{
variable = new Queue<int>();
variable.Enqueue(1);
Thread thread = new Thread(new ThreadStart(DoSomething));
thread.IsBackground = true;
thread.Start();
}
public void DoSomething()
{
int i = variable.Dequeue();
MessageBox.Show(i);
}
}
Upon execution I get an exception saying that the queue is empty when I try to dequeue. Debugging shows that the queue is empty within the context of the thread, but not in the larger class. I assume that C# creates thread-local objects for certain things (but not all, if I were to make an int member variable, I could get its value within the thread without any problems) I know java does similiar things, and the way around it is to declare the member variable as "volatile" or something like that. C# has a similiar construct, but I don't think its what I'm looking for (or at least, I used it and it didn't help...) How would I declare a member variable in C# such that any threads created by the class also can access it? (I'd also really like to understand this stuff better, so links to relevant material would be greatly appreciated)

class MyClass {
public Queue variable;
internal MyClass() {
variable = new Queue();
variable.Enqueue(1);
Thread thread = new Thread(new ThreadStart(DoSomething));
thread.IsBackground = true;
thread.Start();
}
public void DoSomething() {
int i = (int)(variable.Dequeue()); //cast required here
//MessageBox may not play nice from non-ui thread
Console.WriteLine(i);
}
}
works fine with only the smallest edit. The queue is visible from the thread. It's not clear how you reached a different conclusion.
You might consider using a generic Queue<int> to avoid the boxing/unboxing associated with storing value types in non-generic collections.
Better yet, you could avoid a whole bunch of noisy thread-synchronization too by using ConcurrentQueue<T>, seeing as you're sharing this queue between threads.

I think you should change these two lines and it should work.
public Queue<int> variable;
MessageBox.Show(i.ToString());

Related

C# Is it safe to use classes as storage space and access them from different threads?

Say, I have a static class like this
static class PCstatus
{
public static class Cpu
{
//CPU loads
public static int lt;
public static int l1;
public static int l2;
public static int l3;
public static int l4;
//CPU Temp
public static double t0;
//Frequency
}}
Which I'm using as a storage space(should I be doing that?)
And I have 5-6 threads that periodically change different variables in this class(Note: No two threads change the same value) i.e:
First thread:
PCstatus.lt = 0;,
thread.sleep(1000);
Second
PCstatus.l1 = 0;,
thread.sleep(1000);
And then I have another thread that periodically reads all the values from the class, parse them and send them over serial.
Is this a sane way to do it? There is no locking mechanism in the class, so theoretically, one of the threads could try to change a var while the final thread is reading it.
I'm not sure if such a thing can happen, I've run this program for days. So far, haven't noticed any strange behavior.
I can implement a locking mechanism to the class. (bool _isBeingUsed) and make the threads check that value before performing any operation, but I'm not sure if it's necessary.
I know the proper way to output values from threads is to use delegates, but if it's not really necessary, I could do without the added complexity they bring.
Reads and writes to int values in C# are atomic, so you'll never have to worry about data shearing.
However, writing to multiple values within the class is not atomic, so in your example:
First thread:
PCstatus.lt = 0;
thread.sleep(1000);
Second
PCstatus.l1 = 0;
thread.sleep(1000);
There's no guarantee that just because thread 3 sees that lt is 0 that it will also see that l1 is zero. You've potentially got data race issues here.
Also, just because a thread writes to a variable it doesn't mean that other threads will see its value immediately. Instruction reordering of instructions, compiler reordering of instructions and CPU caching strategies may conspire to prevent the write making its way back to main memory and into another thread.
If you're only ever going to change single values from a thread then use methods on the Interlocked class to ensure that your changes are visible across threads. They use a memory barrier to ensure that read/writes to variables propagate across threads.
If you're going to write multiple values in one hit, or if you want to read multiple values in one hit then you'll need to use a lock.
No locking is required, but you should declare those fields volatile to ensure that updates from one thread can be picked up immediately by other threads.
See: https://msdn.microsoft.com/en-us/library/x13ttww7.aspx
Note that you can't declare a double to be volatile. I think for your application you could probably just use a float instead. Otherwise you can use a class that contains an immutable double value.
And I have 5-6 threads that periodically change different variables in this class
Instead of having single storage for results of 5-6 workers you can supply each worker with event. Then anyone who need results can subscribe to it and create local storage, means no thread issues anymore.
Something like
public static class CPUStats
{
public static EventHandler<CPUEventArgs> Measured;
public static CPUStats()
{
Task.Factory.StartNew(() =>
{
while(true)
{
... // poll CPU data periodically
Measured?.Invoke(null, new CPUEventArgs() { LT = lt, L1 = l1, ... });
}
}, TaskCreationOptions.LongRunning);
}
}
public static class StatsWriter
{
static int lt;
static int l1;
...
public static StatsWriter()
{
CPUStats.Measured += (s, e) =>
{
lt = e.LT;
l1 = e.L1;
}
}
public static void Save()
{
var text = $"{DateTime.Now} CPU[{lt},{l1}...]";
... // save text
}
}

how to synchronise multiple threads to a common point

I want to launch an arbitrary number of threads, each executing the same method, but with different parameters. Each thread needs to block at a certain point, and wait until all threads have reached the same point. (Like racers getting into their starting blocks)
I'm stumped on how to make all threads signal to the starter that they are each ready to go.
The solution is to use Barrier Class.
i think that using locking you can synchronize the thread's access.
try this:
lock (lockThis)
{
// Access thread-sensitive resources.
}
I was struggling with multithreading too not so long ago. What you are trying to achieve can be done in a very simple way using just what you know. Here is an idea :
class MyThread
{
private Thread thread;
private bool isWaitingAtPointA = false;
private bool continueWorking = false;
public MyThread ()
{
thread = new Thread(DoMyStuff);
}
private void DoMyStuff()
{
//do stuff
//when at point A :
isWaitingAtPointA = true;
while (!continueWorking)
{
Thread.Sleep(10);
}
isWaitingAtPointA = false;
continueWorking = false;
//do more stuff
}
public bool isAtWaitingPointA()
{
return isWaitingAtPointA;
}
}
Then have a List of MyThread in your main thread that will instantiate all the MyThread objects, start their threads and also unlock them by setting from your main thread continueWorking to true.
Obviously you can check if all the threads are at point A by calling isAtWaitingPointA(). This approach is called "control variables" I believe (please someone correct me if I am wrong) and here the controls variables are the bools isWaitingAtPointA and continueWorking.
The method you want them all to use is here represented by DoMyStuff() which can be defined somewhere else to avoid code redundancies.
I hope this inspires you =)

Boolean Property Getter and Setter Locking

Is there any reason why you would create locks around the getter and setter of a boolean property like this?
private _lockObject = new object();
private bool _myFlag;
public bool MyFlag
{
get
{
lock (_lockObject)
{
return _myFlag;
}
}
set
{
lock (_lockObject)
{
_myFlag = value;
}
}
}
Well, you don't need locks necessarily - but if you want one thread to definitely read the value that another thread has written, you either need locks or a volatile variable.
I've personally given up trying to understand the precise meaning of volatile. I try to avoid writing my own lock-free code, instead relying on experts who really understand the memory model.
EDIT: As an example of the kind of problem this can cause, consider this code:
using System;
using System.Threading;
public class Test
{
private static bool stop = false;
private bool Stop
{
get { return stop; }
set { stop = value; }
}
private static void Main()
{
Thread t = new Thread(DoWork);
t.Start();
Thread.Sleep(1000); // Let it get started
Console.WriteLine("Setting stop flag");
Stop = true;
Console.WriteLine("Set");
t.Join();
}
private static void DoWork()
{
Console.WriteLine("Tight looping...");
while (!Stop)
{
}
Console.WriteLine("Done.");
}
}
That program may or may not terminate. I've seen both happen. There's no guarantee that the "reading" thread will actually read from main memory - it can put the initial value of stop into a register and just keep using that forever. I've seen that happen, in reality. It doesn't happen on my current machines, but it may do on my next.
Putting locks within the property getter/setter as per the code in the question would make this code correct and its behaviour predictable.
For more on this, see this blog post by Eric Lippert.
Reads and writes of bool are atomic.
However the name "flag" indicates that separate threads will be reading/writing until some condition occurred. To avoid unexpected behavior due to optimization you should consider adding the volatile keyword to you bool declaration.
There's no reason to have a lock right there.
Taking a lock may well be appropriate in your design, but it's very doubtful that this is the right granularity.
You need to make your design thread-safe, not individual properties (or even entire objects).

Is the following C# code thread safe?

I am trying to learn the threading in C#. Today I sow the following code at http://www.albahari.com/threading/:
class ThreadTest
{
bool done;
static void Main()
{
ThreadTest tt = new ThreadTest(); // Create a common instance
new Thread (tt.Go).Start();
tt.Go();
}
// Note that Go is now an instance method
void Go()
{
if (!done) { done = true; Console.WriteLine ("Done"); }
}
}
In Java unless you define the "done" as volatile the code will not be safe. How does C# memory model handles this?
Guys, Thanks all for the answers. Much appreciated.
Well, there's the clear race condition that they could both see done as false and execute the if body - that's true regardless of memory model. Making done volatile won't fix that, and it wouldn't fix it in Java either.
But yes, it's feasible that the change made in one thread could happen but not be visible until in the other thread. It depends on CPU architecture etc. As an example of what I mean, consider this program:
using System;
using System.Threading;
class Test
{
private bool stop = false;
static void Main()
{
new Test().Start();
}
void Start()
{
new Thread(ThreadJob).Start();
Thread.Sleep(500);
stop = true;
}
void ThreadJob()
{
int x = 0;
while (!stop)
{
x++;
}
Console.WriteLine("Counted to {0}", x);
}
}
While on my current laptop this does terminate, I've used other machines where pretty much the exact same code would run forever - it would never "see" the change to stop in the second thread.
Basically, I try to avoid writing lock-free code unless it's using higher-level abstractions provided by people who really know their stuff - like the Parallel Extensions in .NET 4.
There is a way to make this code lock-free and correct easily though, using Interlocked. For example:
class ThreadTest
{
int done;
static void Main()
{
ThreadTest tt = new ThreadTest(); // Create a common instance
new Thread (tt.Go).Start();
tt.Go();
}
// Note that Go is now an instance method
void Go()
{
if (Interlocked.CompareExchange(ref done, 1, 0) == 0)
{
Console.WriteLine("Done");
}
}
}
Here the change of value and the testing of it are performed as a single unit: CompareExchange will only set the value to 1 if it's currently 0, and will return the old value. So only a single thread will ever see a return value of 0.
Another thing to bear in mind: your question is fairly ambiguous, as you haven't defined what you mean by "thread safe". I've guessed at your intention, but you never made it clear. Read this blog post by Eric Lippert - it's well worth it.
No, it's not thread safe. You could potentially have one thread check the condition (if(!done)), the other thread check that same condition, and then the first thread executes the first line in the code block (done = true).
You can make it thread safe with a lock:
lock(this)
{
if(!done)
{
done = true;
Console.WriteLine("Done");
}
}
Even in Java with volatile, both threads could enter the block with the WriteLine.
If you want mutual exclusion you need to use a real synchronisation object such as a lock.
onle way this is thread safe is when you use atomic compare and set in the if test
if(atomicBool.compareAndSet(false,true)){
Console.WriteLine("Done");
}
You should do something like this:
class ThreadTest{
Object myLock = new Object();
...
void Go(){
lock(myLock){
if(!done)
{
done = true;
Console.WriteLine("Done");
}
}
}
The reason you want to use an generic object, rather than "this", is that if your object (aka "this") changes at all it is considered another object. Thus your lock does not work any more.
Another small thing you might consider is this. It is a "good practices" thing, so nothing severe.
class ThreadTest{
Object myLock = new Object();
...
void Go(){
lock(myLock){
if(!done)
{
done = true;
}
}
//This line of code does not belong inside the lock.
Console.WriteLine("Done");
}
Never have code inside a lock that does not need to be inside a lock. This is due to the delay this causes. If you have lots of threads you can gain a lot of performance from removing all this unnecessary waiting.
Hope it helps :)

Parameter crossing on Threads C# ERROR

I've a little problem with this code:
This is the "main" method of the app:
private Thread main_process;
private Clases.GestorTR processor;
public void begin()
{
processor = new Clases.GestorTR();
main_process = new Thread(new ThreadStart(processor.ExecuteP));
main_process.Start();
}
I've created a Thread to process other "Transacction Threads" to avoid blocking the GUI.
This is the method ExecuteP, on processor object:
public void ExecuteP()
{
// Readed an DataTable with BD transacction, filled with numbers
foreach (DataRow dr in dtResults.Rows)
{
int Local_number = Convert.toInt32(dr["autonum"].ToString());
ThreadStart starter;
starter = delegate { new QueryBD.QueryCounter(Local_number); };
new Thread(starter).Start();
}
}
This is QueryCounter method of QueryBD class:
....
private void QueryCounter(int _counter)
{
logs.log("ON QUERY_PROCESS: " + _counter);
}
...
Now, the problem. When calling the delegate, some threads are crossing parameters. For example, in the foreach method the log shows correct (1,2,3,4,5,6,7,8) but, in the QueryCounter method (called each time with the new thread, the log shows (1,1,1,4,5,6,6,8) for example. I've also tried to use locks, but the problem is the same. Also testing with the ThreadPool way with the same result.
I think I'm missing something in the foreach loop, because if I debug the first run, the thread is Started, but without action in the log.
Thanks!,
You should try to change some parts of your code like that:
public void ExecuteP()
{
QueryBD facade = new QueryBD.
foreach (DataRow dr in dtResults.Rows)
{
int Local_number = Convert.toInt32(dr["autonum"].ToString());
new Thread(new ParameterizedThreadStart(facade.QueryCounter)).Start(Local_number);
}
}
public void QueryCounter(object _counter)
{
...
}
Hope it works.
Btw. I've created one object called facade and I'm passing that object to various threads. It can also result in some side effects if there will be thread sensitive part of code in the facade object, so you can also consider locking there:
public void QueryCounter(object _counter)
{
lock(this)
{
//
}
}
or providing new QueryBD to each thread, but it can affect performance.
EDIT: Hey, 4 things:
While using ParametrizedThread, the variable passed to Start method of the thread (thread.Start(variable)) is copied at the time of call. Such copied variable is then used in the child thread. Anonymous delegate works different. It keeps the reference to the variable, so when the variable is used by the child thread, it can be changed by the time in your parent thread. That is why you had unpredicted behaviour.
Better explanation you can find here: Differing behavior when starting a thread: ParameterizedThreadStart vs. Anonymous Delegate. Why does it matter?.
The performance depends. If creation of your object is heavy (ex. it creates new connection to DB each time it is created) performance can be seriously affected by creation of many such objects - it is where lock is better. If creation of the object is light, you can create as many objects as you want. It depends.
If you want your code to be run in defined order, you shouldn't use threads at all. If you want to preserve execution order, sequential invoking is the right way - see Hans Passant explanation.

Categories