thread lock object in properties get/set - c#

When using locks, do I need to lock around my get? From my testing I do not need to do so, but I wanted to make sure. Also, how do I format the code I posted so it has the proper schema colors? It is asking me to add more details, but I don't really know what to add- I am moreover asking (from someone more experienced than I) if what I have is correct and will work without throwing cross thread exceptions.
class exam
{
private static readonly exam x = new exam();
private static readonly object lckobj = new object();
private int i;
private int _count;
private exam() { }
public static exam AccessPoint
{
get
{
return x;
}
}
public int myInt
{
get
{
return i;
}
set
{
lock(lckobj)
{
i = value;
}
}
}
public int Count
{
get
{
return _count;
}
set
{
lock(lckobj)
{
_count = value;
}
}
}
}
class myDemo
{
Random r = new Random();
bool b = false;
Thread[] t = new Thread[3];
public myDemo()
{
for(int i=0; i < 3; i++)
{
t[i] = new Thread(new ThreadStart(thread1));
t[i].Start();
}
Thread checks = new Thread(new ThreadStart(checkB));
checks.Start();
}
void checkB()
{
var x = exam.AccessPoint;
while (!b)
{
b = (x.Count >= 10) ? true : false;
Console.WriteLine("\tb:{0}\tCount:{1}", b, x.Count);
Thread.Sleep(100);
}
}
void thread1()
{
var x = exam.AccessPoint;
while (!b)
{
Thread.Sleep(r.Next(500, 1000));
x.myInt = r.Next(1, 10);
x.Count = x.Count + 1;
Console.WriteLine(x.myInt);
}
}
}

Even if you added the lock around the get your code still wouldn't work properly, although there are more possible things that can go wrong if you don't do that.
The following line is problematic in a way that cannot be fixed by locking in Count:
x.Count = x.Count + 1;
Here even if you add locks, it's entirely possible for one thread to read a value, stop before updating, then have another thread read the value, increment the count, and then write it back. That write will be overridden when the first thread continues on. No amount of locking in Count will change that.
Of course, without the lock in Count there is no memory barrier introduced, so reads to that value are allowed to be reading stale values, which can further exacerbate the previous problem.

Reading a value of a variable by multiple threads in the same time is safe.
Writing a value to a variable by multiple threads in the same time is not safe.
Writing a value to a variable by one thread in the same time as one ore more threads are reading from this variable is not safe.
So using the same lock in both setter and getter is required.
Problem described in #Servy answer requires a better solution though. Any flavour of locking mechanism which wraps so called "SELECT FOR UPDATE" (I know this goes for DB but the problem is the same) should be good enough.
You should even reuse the same lock you already have in your code. Make it public since it's readonly and for such situations use it from outside:
lock(exam.lckobj){
exam.myInt = exam.myInt + 1;
}

For integer values use Interlocked.Read and Interlock.Exchange. Very atomic, very thread safe, doesn't carry the weight of a mutex (via lock).

Related

Property of { return 60000 / bpm } always returning 600ms?

I'm trying to build a steady metronome that ticks every beat, but it seems like there is a problem.
How long the metronome waits for each beat is determined by this formula: 60000 / BPM
But, the value seems to return a specific number no matter what value you plug into BPM.
I have a property that returns the value of this formula, along with a bpm integer:
static private int bpm = 125;
static private int BeatLength
{
get
{
return 60000 / bpm;
}
}
static public int beat = 0;
And here is the function that's responsible for the metronome (it runs on a dedicated thread):
public static void RhythmUpdate()
{
lock (threadLock)
{
while (true)
{
Thread.Sleep(BeatLength); // Sleep until the next beat
AddRequest(BeatLength * beat);
beat++;
DefaultSounds.def_CowBell.Play();
OnBeat?.Invoke();
}
}
}
When breakpointing the def_CowBell.Play();, Visual Studio notes that it takes around 600ms to loop. This is how I know the value.
Extra Info:
I'm using OpenGL
Maybe some more if asked...
I appreciate your help in advance.
It turns out that I've been setting BPM on a function, and whenever I made a change to it's initialization it would be overwritten by that new BPM.
public static void StartBeat(int startingBPM)
{
rhythmThread = new Thread(new ThreadStart(RhythmUpdate)); // Initialize new thread
bpm = startingBPM; // < This piece of codde was the source.
rhythmThread.Name = "BeatThread";
rhythmThread.Start(); // Start the thread
}
For now, I'll disable that line of code when testing.

C# MultiThreading: pool of calculators

I want to have a static (global) pool of calculators which are going to be accessed by a lot of different threads.
After some researching I found out that the elements of Arrays are threadsafe.
I thought that it would be good idea to store the diffrent calculators (amount unknown until runtime) in a static array (calculator[] calculators).
How do I ensure that only one calculator is being used by one calculator?
I read the whole msdn documentation so don't post "only" links please.
I have also thought about a bool array "locked" but I can't find a way to implement this threadsafe.
My code so far:
internal static class Calculators
{
private static Semaphore pool;
private static bool[] locked;
private static calcs[] neuralNetworks;
private static Thread[] threads;
internal static Calculators(){
int number = Globals.Number;
pool = new Semaphore(number, number);
locked = new bool[number];
calcs = new calcs[number];
threads = new Thread[number];
for (int index = 0; index < number; index++)
{
// all neuralNetworks are unlocked by default
locked[index] = false;
// generate one network per "countThreads"
calcs[index] = Globals.CalcObj;
// generate one thread for each neural network
threads[index] = new Thread(new ThreadStart());
}
}
private int WhichCalculators()
{
int index;
for (index = 0; index < countThreads; index++)
{
if (locked[index] == false)
{
locked[index] = true;
return index;
}
}
throw new Exception("Calculators was called, but there weren't any networks unused");
}
}
Code Update:
So should it work, if I call "WhichCalculator()" in this method?
private static void doStuff()
{
pool.WaitOne();
Monitor.Enter(thisLock);
try
{
int whichCalculator = WhichCalculator();
locked[whichCalculator] = true;
lock (calculators[whichCalculator])
{
Monitor.Exit(thisLock);
// do stuff
locked[whichCalculator] = false;
}
}
catch
{
Monitor.Exit(thisLock);
}
//Calculate();
pool.Release();
}
Question 2:
Am I right to assume, that the static constructor is going to be executed as soon as (but before) the first time this class or any member of it is going to be accessed?
Yes you have to use lock. But the array and every instance of calculator again.
If you can fill the array before you start the multithreaded section of your code you need not lock the array as well (only reading doesn't make problems due to the static content) but with resizing the array you need to lock every access to it (writing AND reading).
So your code could look like this:
Calculator calc = null;
lock(calculators)
{
calc = calculators[0];
}
lock(calc)
{
// ... do stuff
}
This way the array isn't longer locked then needed and you can lock the calculator itself.
You can lock your array. That would ensure that every array-operation is executed thread-safe.
To ensure, that each object is only used once at a time you can add a flag to it, like calculator.InUse. If you can't add a flag to the class, you can use an extension method.

Set static field value once and use the latest set value in all other threads

As working on multi-threaded application, I have once scenario where I need to assign value to static field. I want to use the latest value of static field in all rest of the threads.
Code is seems like below:
Main() Method:
for (var i = 1; i <= 50; i++)
{
ProcessEmployee processEmployee = new ProcessEmployee();
Thread thread = new Thread(processEmployee.Process);
thread.Start(i);
}
public class ProcessEmployee
{
public void Process(object s)
{
// Sometimes I get value 0 even if the value set to 1 by other thread.
// Want to resolve this issue.
if (StaticContainer.LastValue == 0)
{
Console.WriteLine("Last value is 0");
}
if (Convert.ToInt32(s) == 5)
{
StaticContainer.LastValue = 1;
Console.WriteLine("Last Value is set to 1");
}
// Expectation: want to get last value = 1 in all rest of the threads.
Console.WriteLine(StaticContainer.LastValue);
}
}
public static class StaticContainer
{
private static int lastValue = 0;
public static int LastValue
{
get
{
return lastValue;
}
set
{
lastValue = value;
}
}
}
Question:
Basically, I want to know that once I set specific value to static field by any thread, I want to get the same value (latest value set by another thread) in rest of the threads always.
Please do give me any idea on this.
Thanks in advance!
Basically, I want to know that once I set specific value to static field by any thread, I want to get the same value (latest value set by another thread) in rest of the threads always.
It sounds like you're basically missing a memory barrier. You could work this out with explicit barriers but no locks - or you could just go for the brute-force lock approach, or you could use Interlocked:
private static int lastValue;
public int LastValue
{
// This won't actually change the value - basically if the value *was* 0,
// it gets set to 0 (no change). If the value *wasn't* 0, it doesn't get
// changed either.
get { return Interlocked.CompareExchange(ref lastValue, 0, 0); }
// This will definitely change the value - we ignore the return value, because
// we don't need it.
set { Interlocked.Exchange(ref lastValue, value); }
}
You could use volatile as suggested by newStackExchangeInstance in comments - but I'm never actually sure I fully understand exactly what it means, and I strongly suspect it doesn't mean what most people think it means, or indeed what the MSDN documentation states. You may want to read Joe Duffy's blog post on it (and this one too) for a bit more background.
If two different threads may access the same field/variable and at least one of them will be writing, you need to use some sort of locking. For primitive types use the Interlocked class.

How do I check the state of a thread

I have winform application where i am trying to play multiple videos and i am creating threading for that. My code is :
public String[,] vpath = new String[3, 7];
public Video[,] video = new Video[3, 7];
public static Thread[,] th = new Thread[3, 7];
public void playclick(object sender, EventArgs e)
{
int i, j;
for (j = 0; j <= 7 - 1; j++)
{
for (i = 0; i <= 3 - 1; i++)
{
if (btnp[i, j].Capture)
{
//play();
th[i, j] = new Thread(new ThreadStart(play));
th[i, j].IsBackground = true;
th[i, j].Start();
}
}
}
}
public void play()
{
int i, j;
for (j = 0; j <= 7 - 1; j++)
{
for (i = 0; i <= 3 - 1; i++)
{
if (th[i, j].ThreadState == ThreadState.Running) // Having problem here
{
if (video[i, j].State != StateFlags.Running)
{
video[i, j].Play();
}
}
}
}
}
So with out that if statement it will run all the videos on single button press. But i want to run the particular video which the thread is in ..
pls help me guys
ThreadState is a bitmask-type property (enum has the [Flags] property, that's always the hint), so you don't check it directly using ==, you only need to check the relevant bit:
if ((t.ThreadState & ThreadState.Running) == ThreadState.Running) { ...
Read here about the meanings of the ThreadState values. From reading that and possibly the whole article, or whole book (highly recommended!) you'll also most likely notice that yours is probably not the ideal approach.
Not knowing your exact endgame though, it;s hard to suggest an exact one.
As to why you are getting an exception, HaemEternal nailed that in his comment. You are only initializing one thread at a time, yet you are checking all of them. A null thread object does not have a ThreadState value.
May I suggest though, that you change your design altogether;
There is no need to constantly check which thread was activated. You can change the signature of the Play() method to accept an Object, and you can pass the correct video to the method using that Object.
public void playclick(object sender, EventArgs e)
{
int i, j;
for (j = 0; j <= 7 - 1; j++)
{
for (i = 0; i <= 3 - 1; i++)
{
if (btnp[i, j].Capture)
{
//play();
th[i, j] = new Thread(new ParameterizedThreadStart(play));
th[i, j].IsBackground = true;
th[i, j].Start(video[i,j]);
}
}
}
}
public void play(object video)
{
Video vid = video as Video;
if (vid.State != StateFlags.Running)
{
vid.Play();
}
}
An even better approach is to encapsulate these three elements in a single object that contains a Video object, a Thread object, and a path string.
If you own the Video class, you might even want to make the Thread and the string values fields of that class.
You might even want to create a field on your buttons of type of this new object, so each button will be associated with a button.
This is much more typical of object oriented design. There is no reason you should maintain four separate identically sized arrays, each of different type.
The answer by #tar gives some hints but the code is wrong (as commented by #Sampath).
This come from the fact that ThreadState is implemented in a questionable strange way:
Normally a bitmask state is implemented using for example bit 1 for state on and the
same bit for the opposite off. This is not the case, in fact, for example, the Running
state has a 0 value, whereas the 1 value is taken by StopRequested.
So it is not wise to do a bit check.
A first approach would be to check for state with an or statement:
while (t.ThreadState == ThreadState.Running ||
t.ThreadState == ThreadState.Background)
Application.DoEvents();
t.Join();
Keep in mind that if you start a process in background you will have the
ThreadState.Background enum value returned and not ThreadState.Running,
this is why I have put both.
The better and simpler approach is:
while (t.IsAlive)
Application.DoEvents();
t.Join();
if (th.ThreadState.Equals(ThreadState.Unstarted))
th.Start();

Stop a loop inside a method in C#

Is there any way to stop a running loop inside another method or insert a break statement dynamically in C#?
Thanks
Edit : I want to be able to dynamically intercept the method and insert a break to stop the loop when an event gets triggered in another function.I have several instances of the class and I want to stop the loop in each instance whenever required and manage all the instances. Consider multiple instances to be in a generic list
Example :
List<myclass> objlist=new List<myclass>();
foreach(myclass obj in objlist)
{
obj.loopingfunction().BreakLoop //or something like this (assuming that the loopingfunction is already called)
}
I need this because I want to break the loop once the user stores some huge amount of data.When the user imports the data,I get a event fired. But I cannot keep checking the database from multiple instances since it screws up sqlserver.
This is in an ASP.Net application.
If the whole thing is running in a single thread, it wouldn't make any sense. If the loop is running, then nothing else is running at the same time. If you're running a loop on another thread and the controlling method on another thread, you can either abort the loop thread completely or check a flag inside the loop to decide whether or not you should break and set the flag appropriately in the controlling method.
Update: make that function return a boolean value indicating whether you should break and use it in an "if" statement:
if (myFunctionShouldBreakLoop()) break;
Another option would be to raise a CancelEventArgs during every iteration of the loop. Probably not the most efficient, but another option nonetheless:
private void SomeMethod()
{
for (int i = 0; i <= 100000; i++)
{
Console.WriteLine(i);
if (LoopIncrement != null)
{
CancelEventArgs args = new CancelEventArgs();
LoopIncrement(null, args);
if (args.Cancel)
{
break;
}
}
}
And then elsewhere:
myObj.LoopIncrement += MyHandler;
private void MyHandler(object sender, CancelEventArgs e)
{
if(someCondition)
{
e.Cancel = true;
}
}
This way you can somewhat control the loop from outside....
Have the condition in a locked property.
private Boolean BreakCondition
{
get { lock(_LockObject) { return _BreakCondition; } }
set { lock(_LockObject) { _BreakCondition = value; } }
}
private Boolean _BreakCondition = false;
private Object _LockObject = new Object();
if (this.BreakCondition)
{
break;
}
How about using iterators, and yield magic to solve the problem.
Here is an article on infinite lists that might be useful
http://www.codethinked.com/post/2009/02/04/Infinite-Lists-With-C-Yield.aspx
class Program
{
static void Main(string[] args)
{
Predicate<int> when = i => i > 100 && Console.ReadKey().KeyChar.ToString() == "0";
foreach(var i in Numbers().BreakOn(when))
{
Console.WriteLine(i);
}
Console.ReadLine();
}
private static IEnumerable<int> Numbers()
{
var i = 0;
while(true)
{
yield return i++;
}
}
}
public static class Util
{
public static IEnumerable<int> BreakOn(this IEnumerable<int> sequence, Predicate<int> when)
{
foreach(int i in sequence)
{
if(when(i))
{
yield break;
}
yield return i;
}
}
}
I think you can use flag
bool stop = false;
for(int i=0;i<num;i++)
{
if(stop) break;
}
The short answer is: no. If you don't control the code, then you can't cause the loop to terminate.
If you do control the code, you could build in some sort of cooperation, but it sounds messy. Maybe you can elaborate on why?

Categories

Resources