Get sequence number thread safely - c#

I have a ASP.NET application where I use a sequence number from a database sequence when creating a record in a table with entity framework. I have a stored procedure that retrieves the next value in this sequence that is called from entity framework and I want to ensure that this retrieval is thread-safe.
I used this answer to attempt this in the following class:
public static class SequenceNumber
{
private static object Lock = new object();
public static long Next(Context db)
{
long next = 0;
lock (Lock)
{
next = db.GetNextComplaintNumber().Single().Value;
}
return next;
}
}
Will this ensure thread-safety?

The Next(...) method will be threadsafe but the db.GetNextComplaintNumber() will not be (unless it is implemented to be). The lock ensures that any thread calling Next(...) will have to wait their turn to run whatever is in the lock statement. However if any other threads have access to the object db then they could effectively call db.GetNextComplaintNumber() without calling the Next(...) method so it would not be protected by the lock statement. If you can guarantee db.GetNextComplaintNumber() is only called in the Next(...) method then you should be safe, otherwise you would want to implement thread safety into the db.GetNextComplaintNumber() method.

Related

C# Monitor.Enter not lock if Object lies within another Object

I thought Monitor.Enter works on references to objects as long as the reference to the object or the object itself does not change.
So here is my simple case, I have a class called QueueManager which has an Queue in it. I'm using this object Queue to lock using Monitor.Lock before manipulating the queue. I tried a simple test of calling Monitor.Lock on the queue object and it fails. Any idea why?
public class QueueManager
{
private List<ConversionJob> _jobQueue = new List<ConversionJob>();
public QueueManager()
{
}
public List<ConversionJob> Queue
{ get { return _jobQueue; } }
}
public class Main
{
private QueueManager qMgr = new QueueManager();
public Main()
{
try
{
Monitor.Enter(qMgr.Queue);
throw new Exception();
}
catch (Exception)
{
Monitor.Enter(qMgr.Queue);
}
}
}
This doesn't DEADLOCK!! I can't understand why it doesn't deadlock. I tried this because I suspected the locks were being taken so I put this test code in and I'm surprised.
Monitors are re-entrant - one thread can own a monitor multiple times. The monitor is only unlocked (available for another thread to acquire it) when Exit has been called the same number of times as Enter.
From the docs for Exit:
The calling thread must own the lock on the obj parameter. If the calling thread owns the lock on the specified object, and has made an equal number of Exit and Enter calls for the object, then the lock is released. If the calling thread has not invoked Exit as many times as Enter, the lock is not released.
This doesn't DEADLOCK!!
That is because both calls to Enter() are made from the same thread. Monitor is recursive-reentrant.

Multiple Thread Access a Collection in .net

Supposed there is something like Hashtable created by Hashtable.Synchronized() which is accessed by multiple thread. and the key value pair is Guid and Object in Hashtable .
One of thread need to polling this Hashtable until a specific Guid key had been added into this list by another thread.
Below is my code .
public Hashtable syncHt = new Hashtable();
public void Init()
{
Hashtable ht = new Hashtable();
syncHt = Hashtable.Synchronized(ht);
}
In the application initialization i will call the init();
And In one of thread I will call isExist to find the specific Guid which is added by some other thread .
public bool isExist(Guid sId)
{
while (true)
{
if (syncHt.ContainsKey(sId))
{
return true;
}
}
}
I was wondering whether this loop could be ended. How can I know the Hashtable changed during the polling ?Thanks
Take a look on concurrent collections, especially on ConcurrentBag<T>
Update
About IsExist, here is better solution
Change Hashtableon ConcurrentDictionary<Guid, object>so no lock required
Add items to repositorywithout any lock
ConcurrentDictionary<Guid, object> repository = new ConcurrentDictionary<Guid, object>();
Check repository for existing items
public bool IsExist(Guid id)
{
SpinWait.SpinUntil(() => repository.ContainsKey(id)); - you can add Timout
return true;
}
Here is more about SpinWait
Reading and more important assigning to a reference is always atomic in .NET.
To do atomic operation, use the System.Threading.Interlocked class. See MSDN
I was wondering whether this loop could be ended.
It will end when another (only 1 writer allowed) thread inserts the wanted value, yes.
On MSDN: Hashtable is thread safe for use by multiple reader threads and a single writing thread.
But your solution is very inefficient. The busy-loop can consume a lot of CPU time for nothing. Storing (boxed) Guids in an old style collection isn't perfect either.

Deadlock in Parallel.ForEach with ReaderWriterLockSlim

I have an interesting problem with deadlocks in an my application. There is an in-memory data store that uses a ReaderWriterLockSlim to synchronize reads and writes. One of the read methods uses Parallel.ForEach to search the store given a set of filters. It's possible that one of the filters requires a constant-time read of same store. Here is the scenario that's producing a a deadlock:
UPDATE: Example code below. Steps updated with actual method calls
Given singleton instance store of ConcreteStoreThatExtendsGenericStore
Thread1 gets a read lock on the store - store.Search(someCriteria)
Thread2 attempts to update the store with a write lock - store.Update() -, blocks behind Thread1
Thread1 executes Parallel.ForEach against the store to run a set of filters
Thread3 (spawned by Thread1's Parallel.ForEach) attempts a constant-time read of the store. It tries to get a read lock but is blocked behind Thread2's write lock.
Thread1 cannot finish because it can't join Thread3. Thread2 can't finish because it's blocked behind Thread1.
Ideally what I'd like to do is not try to acquire a read lock if an ancestor thread of the current thread already has the same lock. Is there any way to do this? Or is there a another/better approach?
public abstract class GenericStore<TKey, TValue>
{
private ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();
private List<IFilter> _filters; //contains instance of ExampleOffendingFilter
protected Dictionary<TKey, TValue> Store { get; private set; }
public void Update()
{
_lock.EnterWriterLock();
//update the store
_lock.ExitWriteLock();
}
public TValue GetByKey(TKey key)
{
TValue value;
//TODO don't enter read lock if current thread
//was started by a thread holding this lock
_lock.EnterReadLock();
value = Store[key];
_lock.ExitReadLock();
return value;
}
public List<TValue> Search(Criteria criteria)
{
List<TValue> matches = new List<TValue>();
//TODO don't enter read lock if current thread
//was started by a thread holding this lock
_lock.EnterReadLock();
Parallel.ForEach(Store.Values, item =>
{
bool isMatch = true;
foreach(IFilter filter in _filters)
{
if (!filter.Check(criteria, item))
{
isMatch = false;
break;
}
}
if (isMatch)
{
lock(matches)
{
matches.Add(item);
}
}
});
_lock.ExitReadLock();
return matches;
}
}
public class ExampleOffendingFilter : IFilter
{
private ConcreteStoreThatExtendsGenericStore _sameStore;
public bool Check(Criteria criteria, ConcreteValueType item)
{
_sameStore.GetByKey(item.SomeRelatedProperty);
return trueOrFalse;
}
}
It's unclear what kind of concurrency, memory and performance requirements you actually have so here are a few options.
If you are using .Net 4.0, you could replace your Dictionary with a ConcurrentDictionary and remove your ReaderWriterLockSlim. Keep in mind that doing that will reduce your locking scope and change your method semantics, allowing changes to the contents while you're enumerating (among other things), but on the other hand that will give you a threadsafe enumerator that won't block reads or writes. You'll have to determine if that's an acceptable change for your situation.
If you really do need to lock down the entire collection in this way, you might be able to support a recursive lock policy (new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion)) if you can keep all operations on the same thread. Is performing your search in parallel a necessity?
Alternately, you may want to just get a snapshot of your current collection of values (locking around that operation) and then perform your search against the snapshot. It won't be guaranteed to have the latest data and you'll have to spend a little time on conversion, but maybe that's an acceptable tradeoff for your situation.

Design alternatives to thread implementation of coroutines for converting a push method into a pull method

I have a collection class that holds lots of different types of data in a compressed format. In order to enumerate over all of the values in the collection is has an Execute(Query, IDataWriter) method. You pass it a query that defines what data you want, and then for each piece of matching data it calls a method on the IDataWriter object you pass in.
The IDataWriter interface has 15 different methods, one for each different data type in the collection. Now I need to commit this data to the database and I want to be able to implement IEnumerator<SqlDataRecord> to commit stuff to the database. The problem comes in how to convert calling Execute which dumps a ton of data into the IDataWriter object(push), to a pull method so that the IEnumerator's MoveNext and Current can be used.
I have looked at Coroutines and fibers, but none of the examples I have found seem like they would work for an existing method (Execute in my case) that internally knows nothing of the corountine. So my plan in pseudocode is to do the following using Threads and manual synchronization.
The Execute method would be running in a seperate Thread and I would manually wait and signal it inside each IDataWriter method
class EnumeratorAdapterObject : IEnumerator<SqlDataRecord>, IDataWriter
{
public EnumeratorAdapterObject(Store storeObject)
{
workerThread = new Thread(storeObject.Execute(query, this));
}
public bool MoveNext()
{
if (firstTimeCalled)
{
start worker thread
}
else
{
signal resume
}
block for either a call into an Add method or the Execute thread finishes
if (not anything buffered)
return false
else
return true
}
// 14 other methods like this implemented in IDataWriter, each with different types
public void Add_Decimal(IntvlDataHeader header, decimal data)
{
buffer field of current SqlDataRecord = generate record;
signal main thread
wait for resume signal
}
public SqlDataRecord Current
{
get { return buffer field of current SqlDataRecord; }
}
}
Does this look like a good approach? Does anyone know of any examples or questions that already implement this?
Or would there be a way to take advantage of any of the new 4.0 features? I thought about using a blocking concurrent collection with a limit of 1 thing in it, but then how would the consumer(the IEnumerator's MoveNext) know when the other thread is finished adding stuff?
Rather than doing manual Thread creation and synchronization with Signal/Wait I figured out that I can use Blocking collection with a call to CompleteAdding() when done. The following is a quick example, for my problem above I will wrap this in an object that implements IEnumerator<SqlDataRecord> and IDataWriter, so instead of the GenerateStuff call I will be calling Execute and the Add_* methods will be the ones calling col.Add(new SqlDataRecord(....))
static void Main(string[] args)
{
var col = new BlockingCollection<int>(1);
Task.Factory.StartNew(
() =>
{
GenerateStuff(col);
col.CompleteAdding();
});
while (!col.IsCompleted)
{
Thread.Sleep(100);
int result;
if (!col.TryTake(out result, -1))
{
break;
}
Console.WriteLine("Got {0}", result);
}
Console.WriteLine("Done Adding!");
}
static void GenerateStuff(BlockingCollection<int> col)
{
for (int i = 0; i < 10; i++)
{
Thread.Sleep(10);
Console.WriteLine("Adding {0}", i);
col.Add(i);
Console.WriteLine("Added {0}", i);
}
}
This also has the advantage that the worker thread that is running the Execute will be generating the next result concurrently with the IEnumerator returning Current and the sql code doing whatever it does to commit the data. With the manual thread signalling only one thread would ever run at a time.

Lazy<T> ExecutionAndPublication - Examples That Could Cause Deadlock

The documentation for LazyThreadSafetyMode states that using the value ExecutionAndPublication could cause deadlocks if the initialization method (or the default constructor, if there is no initialization method) uses locks internally. I am trying to get a better understanding of examples that could cause a deadlock when using this value. In my use of this value, I am initializing a ChannelFactory. I cannot see the ChannelFactory's constructor using any internal locks (reviewing the class with Reflector), so I believe this scenario does not fit the possible deadlock situation, but I am curious what situations could cause a deadlock as well as if there could be a possible deadlock initializing the ChannelFactory.
So, to summarize, my questions are:
Is it possible to cause a deadlock initializing the ChannelFactory using ExecutionAndPublication?
What are some possible ways to cause a deadlock initializing other objects using ExecutionAndPublication?
Suppose you have the following code:
class x
{
static Lazy<ChannelFactory<ISomeChannel>> lcf =
new Lazy<ChannelFactory<ISomeChannel>>(
() => new ChannelFactory<ISomeChannel>("someEndPointConfig"),
LazyThreadSafetyMode.ExecutionAndPublication
);
public static ISomeChannel Create()
{
return lcf.Value.CreateChannel();
}
}
It's as documented – if it doesn't use any locks, this usage cannot cause any deadlocks.
Imagine that you have a lazy value that you initialize by reading from a database, but you want to make sure that only one thread is accessing the DB at any moment. If you have other code that accesses the DB, you could have a deadlock. Consider the following code:
void Main()
{
Task otherThread = Task.Factory.StartNew(() => UpdateDb(43));
Thread.Sleep(100);
Console.WriteLine(lazyInt.Value);
}
static object l = new object();
Lazy<int> lazyInt = new Lazy<int>(Init, LazyThreadSafetyMode.ExecutionAndPublication);
static int Init()
{
lock(l)
{
return ReadFromDb();
}
}
void UpdateDb(int newValue)
{
lock(l)
{
// to make sure deadlock occurs every time
Thread.Sleep(1000);
if (newValue != lazyInt.Value)
{
// some code that requires the lock
}
}
}
Init() reads from the DB, so it has to use the lock. UpdateDb() writes to the DB, so it needs the lock too, and since Lazy uses a lock internally too in this case, it causes deadlock.
In this case, it would be easy to fix the deadlock by moving the access to lazyInt.Value in UpdateDb() outside the lock statement, but it may not be so trivial (or obvious) in other cases.

Categories

Resources