How to make objects Threadsafe on c#? - c#

I have a an application that requires threading in most cases. Most of the time I will encounter errors or wrong values because the object was updated prior to its execution for each thread.
Do you have any suggestion how to make objects be thread safe and making sure that objects have the correct for each thread? Should I make my variables static?

The first thing you should do is draw a Happens-Before graph of the problem you want to solve by multi-threading. If you can't draw your design, it's too complicated.
For example, this is a happens-before graph of a method which takes two arrays of ints and outputs the sum of all elements.
Once you have your happens-before graph it is really easy to see what has to happen before something else, but more importantly it shows you what does not have to happen before something else.
In this example, you can get the sums of both array1 and array2 at the same time.
You can also get sum1 at the same time as sum2 since they don't depend on each other.
Adding the sums to TotalSum1 can be done in either order, (but you will need to lock around the addition step since you can't do the addition at the same time as another).
C# .net 4.0 has a lot of useful capabilities for parallel programming.
I recommend this book Parallel Programming with Microsoft .Net -- just use the bookmarks on the left to navigate it. It covers the parallel patterns of Loops, Tasks, Aggregation, Futures, and Pipelines.
In the example above, I would use a Task1 to get the Array1 and Task2 to get the Array2, then within both of those I would use the Aggregation patterns built into a Parallel.For loop for the array sums, I would need to use locks or an Interlocked.Add to accumalate the subTotals, then wait for the tasks to finish and return the result.
Useful Patterns:
Task
Parallel Loops
Producer/Consumer
Pipeline
Worklist
MapReduce
Useful Tools:
Task Parallel Library
Parallel.For
Parallel.Foreach,
Tasks
PLinq
Concurrent DataStructures
ConcurrentQueue
etc.
Locking
'lock' keyword
Monitor (same functionality as 'lock')
Semaphores
Spinlocks
Read/Write locks
Hardware Atomic Operations
Interlocked.Increment
Interlocked.Add
Interlocked.CompareAndSwap
Assignments to machine word length variables like int
Message Passing
MPI
Barriers
etc.
Basically, understand your problem first then choose the tools/patterns to solve it.

Look into using the lock statement for any resources that you need to make thread safe.
http://msdn.microsoft.com/en-us/library/c5kehkcz.aspx
class Account
{
decimal balance;
private Object thisLock = new Object();
public void Withdraw(decimal amount)
{
lock (thisLock)
{
if (amount > balance)
{
throw new Exception("Insufficient funds");
}
balance -= amount;
}
}
}
This would be my first step. Also you can look into the Monitor class.
http://msdn.microsoft.com/en-us/library/system.threading.monitor.aspx
These are the two basic ways that you can protect your resources during concurrent operations. There are many other ways such as mutexes, sempahores, conditional read/write locks,etc.

Start here: Synchronizing Data for Multithreading
Basically, you'll need to use a mutex. In .NET every object can act as a mutex, so you can use the lock keyword on any object to ensure mutual exclusions.

Related

How to store results from tasks running in threadpool?

I have a problem with a threadpool efficiency. I'm not sure I understand the whole concept. I did a lot of reading before asking that question and I know that threadpool is a good solution if you have a lot of small, relatively quick functions AND what's more important - non-blocking tasks. Using lock is very bad in threadpool.
And here is my question: How to return values from threadpool functions? If you have functions to run they probably produce some results, right? It's good to store those results somewhere. Where?
I'm running c.a. 200k very quick functions in a threadpool. The results I store in the List. Of course I have to do:
lock(lockobj)
{
myList.Add(result);
}
So, is this the right way? I mean, if your functions returns SOMETHING, you have to store them in some kind of collection. It has to be a blocking collection. So, I started thinking... "Blocking is very bead in threadpool, but you have to do this, at least once - at the end of every function
How to store/return results from functions running in threadpool?
Thanks!
JB
EDIT: By "function" I mean...
ThreadPool.QueueUserWorkItem(state =>
{
Result r = function(); // previously named "Task"
lock(lockobj)
{
allResults.Add(r);
}
}
If you don't want to block the ThreadPool threads use a lock-free approach. ConcurrentQueue is currently lock-free (as of .NET 4.6.2) when you enqueue items.
So simply do this:
public static ConcurrentQueue<Result> AllResults { get; } = new ConcurrentQueue<Result>();
ThreadPool.QueueUserWorkItem(state =>
{
Result r = function();
AllResults.Enqueue(r);
}
This will guarantee you don't block ThreadPool threads.
Any kind of collection that is thread safe/synchronized will do. There are plenty in .net framework.
You can also use volatile variables to store data between multiple threads - but this is usually considered a bad practice.
Another approach can be to schedule those operations on tasks that can produce results, they run by default on the thread pool and you can get the return values by awaiting the methods and checking the Result of the Task that is returned.
Finally you can write your own code in order to synchronize access to certain regions of code/variables etc using stuff like lock, semaphores, mutex etc

Threads operating on the one instance of a method

I'm creating an app, where I have 50x50 map. On this map I can add dots, which are new instances of the class "dot". Every dot has it's own thread, and every thread connected with a specific dot operates on the method "explore" of the class, and in this method there is another method "check_place(x,y)" which is responsible for checking if some place on the map was already discovered. If not, the static variable of the class "num_discovered" should be incremented. This single instance of the method "check_place(x,y)" should be accessed in the real-time by every thread started in the app.
Constructor:
public dot(Form1 F)
{
/...
thread = new System.Threading.Thread(new System.Threading.ThreadStart(explore)); //wątek wykonujący metodę explore klasy robot
thread.Start();
}
check_place(x,y) method:
static void check_place(int x, int y)
{
lock (ob)
{
if (discovered[x, y] == false)
{
discovered[x, y] = true;
num_discovered += 1;
}
}
}
In the explore method I'm invoking method "check_place(x,y)" like this:
dot.check_place(x, y);
Is it enough to achieve a situation where in the single time only one dot can check if place was already discovered?
Is it enough to achieve a situation where in the single time only one dot can check if place was already discovered?
Yes. But what's the point?
If threads are spending all of their time waiting on other threads, what have you gained from being multi-threaded?
There are three (sometimes overlapping) reasons to spawn more threads:
To make use of more than one core at the same time: overall throughput increases.
To have work done while another thread is waiting on something else (typically I/O from file, DB or network): overall throughput increases.
To respond to user interaction while work is being done: overall throughput decreases, but it feels faster to the user as they are separately being reacted to.
Here the last doesn't apply.
If your "checking" involved I/O then the second might apply, and this strategy might make sense.
The first could well apply, but because all the threads are spending most of their time waiting on other threads, you don't gain an improvement in throughput.
Indeed, because there is overhead involved in setting up threads and switching between them, this code will be slower than just having one thread do everything: If only one thread can work at a time, then only have one thread!
So your use of a lock here is correct in that it prevents corruption and errors, but pointless in that it makes everything too slow.
What to do about this:
If your real case involves I/O or other reasons why the threads in fact spend most of their time out of each others' way, then what you have is fine.
Otherwise you've got two options.
Easy: Just use one thread.
Hard: Have finer locking.
One way to have finer locking would be to do double-checking:
static void check_place(int x, int y)
{
if (!discovered[x, y])
lock (ob)
if (!discovered[x, y])
{
discovered[x, y] = true;
num_discovered += 1;
}
}
Now at the very least some threads will skip past some cases where discovered[x, y] is true without holding up the other threads.
This is useful when a thread is going to get a result at the end of the locked period. Its still not good enough here though, because it's just going to move on quickly to a case were it fights for the lock again.
If our lookup of discovered were itself thread-safe and that thread-safety was finely grained, then we could make some progress:
static void check_place(int x, int y)
{
if (discovered.SetIfFalse(x, y))
Interlocked.Increment(ref num_discovered)
}
So far though we've just moved the problem around; how do we make SetIfFalse thread-safe without using a single lock and causing the same problem?
There are a few approaches. We could use striped locks, or low-locking concurrent collections.
It seem that you have a fixed-size structure of 50×50, in which case this isn't too hard:
private class DotMap
{
//ints because we can't use interlocked with bools
private int[][] _map = new int[50][];
public DotMap()
{
for(var i = 0; i != 50; ++i)
_map[i] = new int[50];
}
public bool SetIfFalse(int x, int y)
{
return Interlocked.CompareExchange(ref _map[x][y], 1, 0) == 0;
}
}
Now our advantages are:
All of our locking is much lower-level (but note that Interlocked operations will still slow down in the face of contention, albeit not as much as lock).
Much of our locking is out of the way of other locking. Specifically, that in SetIfFalse can allow for separate areas to be checked without being in each others way at all.
This is neither a panacea though (such approaches still suffer in the face of contention, and also bring their own costs) nor easy to generalise to other cases (changing SetIfFalse to something that does anything more than check and change that single value is not easy). It's still quite likely that even on a machine with a lot of cores this would be slower than the single-threaded approach.
Another possibility is to not have SetIfFalse thread-safe at all, but to ensure that the threads where each partitioned from each other so that they were never going to hit the same values and that the structure is safe in the case of such multi-threaded access (fixed arrays of elements above machine word-size are thread-safe when threads only ever hit different indices, must mutable structures where one can Add and/or Remove are not).
In all, you've got the right idea about how to use lock to keep threads from causing errors, and that is the approach to use 98% of the time when something lends itself well to multithreading because it involves threads waiting on something else. Your example though hits that lock too much to benefit from multiple cores, and creating code that does is not trivial.
Your performance on this could potentially be pretty bad - I recommend using Task.Run here to increase efficiency when you need to run your explore method on multiple threads in parallel.
As far as locking and thread safety, if the lock in check_place is the only place you're setting bools in the discovered variable and setting the num_discovered variable, the existing code will work. If you start setting them from somewhere else in the code, you will need to use locks there as well.
Also, when reading from these variables, you should read these values into local variables inside other locks using the same lock object to maintain thread safety here as well.
I have other suggestions but those are the two most basic things you need here.

What is the correct usage of ConcurrentBag?

I've already read previous questions here about ConcurrentBag but did not find an actual sample of implementation in multi-threading.
ConcurrentBag is a thread-safe bag implementation, optimized for scenarios where the same thread will be both producing and consuming data stored in the bag."
Currently this is the current usage in my code (this is simplified not actual codes):
private void MyMethod()
{
List<Product> products = GetAllProducts(); // Get list of products
ConcurrentBag<Product> myBag = new ConcurrentBag<Product>();
//products were simply added here in the ConcurrentBag to simplify the code
//actual code process each product before adding in the bag
Parallel.ForEach(
products,
new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount },
product => myBag.Add(product));
ProcessBag(myBag); // method to process each items in the concurrentbag
}
My questions:
Is this the right usage of ConcurrentBag? Is it ok to use ConcurrentBag in this kind of scenario?
For me I think a simple List<Product> and a manual lock will do better. The reason for this is that the scenario above already breaks the "same thread will be both producing and consuming data stored in the bag" rule.
Also I also found out that the ThreadLocal storage created in each thread in the parallel will still exist after the operation (even if the thread is reused is this right?) which may cause an undesired memory leak.
Am I right in this one guys? Or a simple clear or empty method to remove the items in the ConcurrentBag is enough?
This looks like an ok use of ConcurrentBag. The thread local variables are members of the bag, and will become eligible for garbage collection at the same time the bag is (clearing the contents won't release them). You are right that a simple List with a lock would suffice for your case. If the work you are doing in the loop is at all significant, the type of thread synchronization won't matter much to the overall performance. In that case, you might be more comfortable using what you are familiar with.
Another option would be to use ParallelEnumerable.Select, which matches what you are trying to do more closely. Again, any performance difference you are going to see is likely going to be negligible and there's nothing wrong with sticking with what you know.
As always, if the performance of this is critical there's no substitute for trying it and measuring.
It seems to me that bmm6o's is not correct. The ConcurrentBag instance internally contains mini-bags for each thread that adds items to it, so item insertion does not involve any thread locks, and thus all Environment.ProcessorCount threads may get into full swing without being stuck waiting and without any thread context switches. A thread sinchronization may require when iterating over the collected items, but again in the original example the iteration is done by a single thread after all insertions are done. Moreover, if the ConcurrentBag uses Interlocked techniques as the first layer of the thread synchronization, then it is possible not to involve Monitor operations at all.
On the other hand, using a usual List<T> instance and wrapping each its Add() method call with a lock keyword will hurt the performance a lot. First, due to the constant Monitor.Enter() and Monitor.Exit() calls that each require to step deep into the kernel mode and to work with Windows synchronization primitives. Secondly, sometimes occasionally one thread may be blocked by the second thread because the second thread has not finished its addition yet.
As for me, the code above is a really good example of the right usage of ConcurrentBag class.
Is this the right usage of ConcurrentBag? Is it ok to use ConcurrentBag in this kind of scenario?
No, for multiple reasons:
This is not the intended usage scenario for this collection. The ConcurrentBag<T> is intended for mixed producer-consumer scenarios, meaning that each thread is expected to add and take items from the bag. Your scenario is nothing like this. You have many threads that add items, and zero threads that take items. The main application for the ConcurrentBag<T> is for making object-pools (pools of reusable objects that are expensive to create or destroy). And given the availability of the ObjectPool<T> class in the Microsoft.Extensions.ObjectPool package, even this niche application for this collection is contested.
It doesn't preserve the insertion order. Even if preserving the insertion order is not important, getting a shuffled output makes the debugging more difficult.
It creates garbage that have to be collected by the GC. It creates one WorkStealingQueue (internal class) per thread, each containing an expandable array, so the more threads you have the more objects you allocate. Also each time it is enumerated it copies all the items in an array, and exposes an IEnumerator<T> GetEnumerator() property that is boxed on each foreach.
There are better options available, offering both better performance and better ordering behavior.
In your scenario you can store the results of the parallel execution in a simple array. Just create an array with length equal to the products.Count, switch from the Parallel.ForEach to the Parallel.For, and assign the result directly to the corresponding slot of the results array without doing any synchronization at all:
List<Product> products = GetAllProducts(); // Get list of products
Product[] results = Product[products.Count];
Parallel.For(0, products.Count,
new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount },
i => results[i] = products[i]);
ProcessResults(results);
This way you'll get the results with perfect ordering, stored in a container that has the most compact size and the fastest enumeration of all .NET collections, doing only a single object allocation.
In case you are concerned about the thread-safety of the above operation, there is nothing to worry about. Each thread writes on different slots in the results array. After the completion of the parallel execution the current thread has full visibility of all the values that are stored in the array, because the TPL includes the appropriate barriers when tasks are queued, and at the beginning/end of task execution (citation).
(I have posted more thoughts about the ConcurrentBag<T> in this answer.)
If List<T> is used with a lock around Add() method it will make threads wait and will reduce the performance gain of using Parallel.ForEach()

Array and Safe Access by Threads

If I have an array that can/will be accessed by multiple threads at any given point in time, what exactly causes it to be non-thread safe, and what would be the steps taken to ensure that the array would be thread safe in most situations?
I have looked extensively around on the internet and have found little to no information on this subject, everything seems to be specific scenarios (e.g. is this array, that is being accessed like this by these two threads thread-safe, and on, and on). I would really like of someone could either answer the questions I laid out at the top, or if someone could point towards a good document explaining said items.
EDIT:
After looking around on MSDN, I found the ArrayList class. When you use the synchronize method, it returns a thread-safe wrapper for a given list. When setting data in the list (i.e. list1[someNumber] = anotherNumber;) does the wrapper automatically take care of locking the list, or do you still need to lock it?
When two threads are accessing the exact same resource (e.g., not local copies, but actually the same copy of the same resource), a number of things can happen. In the most obvious scenario, if Thread #1 is accessing a resource and Thread #2 changes it mid-read, some unpredictable behavior can happen. Even with something as simple as an integer, you could have logic errors arise, so try to imagine the horrors that can result from improperly using something more complicated, like a database access class that's declared as static.
The classical way of handling this problem is to put a lock on the sensitive resources so only one thread can use it at a time. So in the above example, Thread #1 would request a lock to a resource and be granted it, then go in to read what it needs to read. Thread #2 would come along mid-read and request a lock to the resource, but be denied and told to wait because Thread #1 is using it. When Thread #1 finishes, it releases the lock and it's OK for Thread #2 to proceed.
There are other situations, but this illustrates one of the most basic problems and solutions. In C#, you may:
1) Use specific .NET objects that are managed as lockable by the framework (like Scorpion-Prince's link to SynchronizedCollection)
2) Use [MethodImpl(MethodImplOptions.Synchronized)] to dictate that a specific method that does something dangerous should only be used by one thread at a time
3) Use the lock statement to isolate specific lines of code that are doing something potentially dangerous
What approach is best is really up to your situation.
If I have an array that can/will be accessed by multiple threads at
any given point in time, what exactly causes it to be non-thread safe,
and what would be the steps taken to ensure that the array would be
thread safe in most situations?
In general terms, the fact that the array is not thread-safe is the notion that two or more threads could be modifying the contents of the array if you do not synchronize access to it.
Speaking generally, for example, let's suppose you have thread 1 doing this work:
for (int i = 0; i < array.Length; i++)
{
array[i] = "Hello";
}
And thread 2 doing this work (on the same shared array)
for (int i = 0; i < array.Length; i++)
{
array[i] = "Goodbye";
}
There isn't anything synchronizing the threads so your results will depend on which thread wins the race first. It could be "Hello" or "Goodbye", in some random order, but will always be at least 'Hello' or 'Goodbye'.
The actual write of the string 'Hello' or 'Goodbye' is guaranteed by the CLR to be atomic. That is to say, the writing of the value 'Hello' cannot be interrupted by a thread trying to write 'Goodbye'. One must occur before or after the other, never in between.
So you need to create some kind of synchronization mechanism to prevent the arrays from stepping on each other. You can accomplish this by using a lock statement in C#.
C# 3.0 and above provide a generic collection class called SynchronizedCollection which "provides a thread-safe collection that contains objects of a type specified by the generic parameter as elements."
Array is thread safe if it is named public and static keywords - instant is not guaranteed - as the System.Array implements the ICollection interface which define some synchronize method to support synchronizing mechanism.
However, coding to enumerate through the array's item is not safe, developer should implement lock statement to make sure there is no change to the array during the array enumeration.
EX:
Array arrThreadSafe = new string[] {"We", "are", "safe"};
lock(arrThreadSafe.SyncRoot)
{
foreach (string item in arrThreadSafe)
{
Console.WriteLine(item);
}
}

creating thread or parallel programming for multiple dropdown boxes populated by SQL Server

So I have a poco class with extension method that populates a select list as shown below. Suppose I have 10 dropdown boxes and each extension method goes to the database and populates the SelectList.
Now I want to start each method as a thread is this a good idea.... I am seeking for advice and things that would be better to increase performance and speed. Is the thread more expensive than a sql connection? Should I run two processes per thread ,three, four...?
class person
{
public person()
{
CrimesListbox1 = CrimesListBox1.populate();
CrimesListBox2 = CrimesListBox1.populate();
CrimesListBox3 = CrimesListBox1.populate();
//so instead of the above way should i..... do the following?
Thread t = new Thread (this.CrimesListBox1.populate()); // Kick off a new thread
t.Start();
Thread t2 = new Thread (this.CrimesListBox2.populate());
t2.Start();
}
public SelectList CrimesListBox1{get;set}
public SelectList CrimesListBox2{get;set}
public static SelectList populate(this SelectList Object)
{
CrimesDataContext LinqCtx = new CrimesDataContext ();
var CrimesListBox1=
(
from x in LinqCtx.CrimesListBox1
orderby x.Crimes
select x
);
Object=
new SelectList
(
CrimesListBox1, "CrimeId", "CrimeName"
);
return Object;
}
}//end of the person class
Now I want to start each method as a thread is this a good idea....
No. It is an idea starting with "S" and ending with "D" and having 4 letters.
Threads have overhead. Lets get into the points:
It may make little sense really to use async programming of any form - simply not going to result in avisible difference unltess the boxes are long.
if they are, though, there may bea benefit. But using separate threads is bordering not knowing the .NET framework.
Solution:
For current .NET use TASKS. The Tasks framework is done for exactly that.
For .NET 4.5 use async methods.
Those use internally boh a thread POOL, so they do not open another thread for every small request, but keep a pool of worker threads whih get assigned those small tasks. Because creating and destroying the thread has a nontrivial overhead. The ThreadPool (pre .net 4.0 solution), the tasks framework and the async methods in the next version where made exaxctly for NOT having to deal with those items. Tasks are good enough and available now.
Using threading for this purpose is a bad idea. Consider this rule of thumb. Don't use threading when competing for the same resource. A resource can be disk, db, screen, user interface. Your db does not get faster when using threading, because the amount of work of work is the same on the same resource.
Just like computing a cpu heavy calculation on a single core will not be faster by splitting the work using threading. Just like reading a number of files from a single disk will not be faster by splitting the work with threading.
These examples use a single resource, cpu and disk, which is working as fast as it can.
Threading is useful when you want to combine two resources. Reading from disk while performing cpu calculation, threading can be a benefit to prefetch data for the calculation etc.
You can use Parallel Linq(PLinq) if you are using .Net 4.0 or higher.

Categories