Is there a way to implement a lock free static configuration data? - c#

public class MyConfigurationData
{
public double[] Data1 { get; set; }
public double[] Data2 { get; set; }
}
public class MyClass
{
private static object SyncObject = new object();
private static MyConfigurationData = null;
private static MyClass()
{
lock(SyncObject)
{
//Initialize Configuration Data
//This operation is bit slow as it needs to query the DB to retreive configuration data
}
}
public static MyMethodWhichNeedsConfigurationData()
{
lock(SyncObject)
{
//Multilple threads can call this method
//I lock only to an extent where I attempt to read the configuration data
}
}
}
In my application I need to create the configuration data only once and use it several multiple times. In other words, I write once and read many times. And also, I wanted to ensure that read should not happen till write operation is finished. In other words, I don't want to read MyConfigurationData as NULL.
What I know is the static constructor is called only once in an AppDomain. But, while I am preparing the configuration data, if any thread tries to read this data how would I ensure synchronization effectivey? In the end, I wanted to improve the performance of my read operation.
Can I implement my objective in a lock-free manner?

From MSDN:
A static constructor is used to initialize any static data, or to perform a particular action that needs performed once only. It is called automatically before the first instance is created or any static members are referenced.
So you don't need to use lock in your code, it is actually thread-safe. Your static constructor is called before MyMethodWhichNeedsConfigurationData is referenced.
public class MyClass
{
private static MyConfigurationData = null;
private static MyClass()
{
}
public static MyMethodWhichNeedsConfigurationData()
{
}
}

As long as you are only ever reading the data, it should already be thread-safe. Very few data-structures are not thread-safe when just reading (the obvious counter-examples might include lazy loading). Note that the static constructor is automatically synchronized by the runtime, so you don't need to concern yourself with multiple threads running the "Initialize Configuration Data" step.
So: as long as nothing ever mutates the data, you are already safe. You could also make it harder to get wrong by hiding the data behind an immutable interface, i.e.
public class ConfigurationData {
// or some similar immutable API...
public double GetData1(int index) { return data1[index]; }
public double GetData2(int index) { return data2[index]; }
private readonly double[] data1, data2;
public ConfigurationData(double[] data1, double[] data2) {
this.data1 = data1;
this.data2 = data2;
}
}
Then you don't need any locks:
public class MyClass
{
private static MyConfigurationData;
private static MyClass()
{
//Initialize Configuration Data
MyConfigurationData = ...
//This operation is bit slow as it needs to query the DB to retreive configuration data
}
public static MyMethodWhichNeedsConfigurationData()
{ //Multilple threads can call this method
var config = MyConfigurationData;
}
}
Note that removing the locks improves parallelism; it doesn't change raw single-threaded performance.
That said: I should advise against static data generally; it makes it very hard to test, and makes it tricky to do things like multi-tenancy if your needs change. It may be more prudent to have a single configuration instance, but pass it into the system as some form of context. Either approach can be used successfully, though - this is just something to be aware of.

I think you should use Singleton pattern and put your configuration initialization logic in "GetInstance" method which would return the instance of your class.
This way you would not need any locking mechanism for Read.

Related

How do I mark a method as not-threadsafe?

Every so often I hit upon this problem and ignore it, but it started gnawing at me today.
private readonly object _syncRoot = new object();
private List<int> NonconcurrentObject { get; } = new List<int>();
public void Fiddle()
{
lock (_syncRoot)
{
// ...some code...
NonconcurrentObject.Add(1);
Iddle();
}
}
public void Twiddle()
{
lock (_syncRoot)
{
// ...some different code...
NonconcurrentObject.Add(2);
Iddle();
}
}
private void Iddle()
{
// NOT THREADSAFE! DO NOT CALL THIS WITHOUT LOCKING ON _syncRoot
// ......lots of code......
NonconcurrentObject.Add(3);
}
I have multiple public methods of a class with some code that is not inherently threadsafe (the List above is a trivial example). I want to use helper methods for the code shared between them (as anyone would), but in splitting off the shared code I'm faced with a dilemma: do I use recursive locking in the helper methods or not? If I do, my code is wasteful and possibly less performant. If I don't (as above), the helper method is no longer threadsafe and open to a nasty race condition if called by some other method in the future.
How can I (elegantly and robustly) signal that a method isn't threadsafe?
You use doc comments.
///<remarks>not thread safe</remarks>
You could use custom attributes to mark methods that are not thread safe.
The advantage over comments is that it gives you options for further processing (via reflection) if you wish to do so at a later date.
public class NotThreadSafe : Attribute
{
//...
}
public class MyClass
{
[NotThreadSafe]
public void MyMethod()
{
//...
}
}
You could add the _Unsafe suffix to your utility methods that are not protected with locks.
Advantages: It reminds you that you are doing dangerous things, and so that you must be extra careful. A small mistake could cost you days of debugging in the future.
Disadvantages: Not very pretty, and can be confused with the unsafe keyword.
private void Iddle_Unsafe()
{
NonconcurrentObject.Add(3);
}
public void Twiddle()
{
lock (_syncRoot)
{
NonconcurrentObject.Add(2);
Iddle_Unsafe();
}
}

Thread safe Singletion static method initialization

I'm implementing a singleton pattern, and need the initialization to be thread safe.
I've seen several ways to do it, like using the double check lock implementation, or other techniques (i.e.: http://csharpindepth.com/articles/general/singleton.aspx)
I wanted to know if the following approach, which is similar to the fourth version in the article, is thread safe. I'm basically calling a method in the static field initializer, which creates the instance. I don't care about the lazyness. Thanks!
public static class SharedTracerMock
{
private static Mock<ITracer> tracerMock = CreateTracerMock();
private static Mock<ITracer> CreateTracerMock()
{
tracerMock = new Mock<ITracer>();
return tracerMock;
}
public static Mock<ITracer> TracerMock
{
get
{
return tracerMock;
}
}
}
Yes, that's thread-safe - although it's not the normal singleton pattern, as there are no instances of your class itself. It's more of a "single-value factory pattern". The class will be initialized exactly once (assuming nothing calls the type initializer with reflection) and while it's being initialized in one thread, any other thread requesting TracerMock will have to wait.
Your code can also be simplified by removing the method though:
public static class SharedTracerMock
{
private static readonly Mock<ITracer> tracerMock = new Mock<ITracer>();
public static Mock<ITracer> TracerMock { get { return tracerMock; } }
}
Note that I've made the field readonly as well, which helps in terms of clarity. I generally stick trivial getters all on one line like this too, to avoid the bulk of lots of lines with just braces on (7 lines of code for one return statement feels like overkill).
In C# 6, this can be simplified even more using a readonly automatically implemented property:
public static class SharedTracerMock
{
public static Mock<ITracer> TracerMock { get; } = new Mock<ITracer>();
}
Of course, just because this property is thread-safe doesn't mean that the object it returns a reference to will be thread-safe... without knowing about Mock<T>, we can't really tell that.

Is it good practice to lock on a threaded instance of an object being used throughout an application?

Every example I've ever seen of locking uses a private object to lock specific blocks of code, and Thread Synchronization (C#) gives the same kind of example, but also says "Strictly speaking, the object provided is used solely to uniquely identify the resource being shared among multiple threads, so it can be an arbitrary class instance. In practice, however, this object usually represents the resource for which thread synchronization is necessary." (Emphasis mine.) In my example here, and in my code, there is only one instance of "MyClass", which is running on its own thread, and a reference to it is passed around to various other classes.
Is it OK to lock on the MyClass reference and then call Ready(), or should I instead put a private object() within MyClass and lock on that, as shown in the LockedReady() method? Thank you for your answer, in advance.
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var uc = new UserClass();
uc.DoThings();
}
}
public class MyClass
{
public bool Ready()
{
//determine if the class is ready to perform its function
//assumes that the instance of MyClass is locked,
//as shown in UserClass.DoThings
}
private object _readyLock = new object();
public bool LockedReady()
{
lock (_readyLock)
{
//determine if the class is ready to perform its function
//no assumption made that the object is locked, as
//shown in AnotherClass.DoAnotherThing()
}
}
}
public class UserClass
{
private MyClass _myc;
public UserClass()
{
var t = new Thread(SetupMyClass);
t.Start();
}
private void SetupMyClass()
{
_myc = new MyClass();
}
public void DoThings()
{
lock(_myc)
{
if (_myc.Ready())
{
//Do things
}
}
}
public void DoOtherThings()
{
var ac = new AnotherClass(_myc);
ac.DoAnotherThing();
}
}
public class AnotherClass
{
private MyClass _myc;
public AnotherClass(MyClass myClass)
{
_myc = myClass;
}
public void DoAnotherThing()
{
if (_myc.LockedReady())
{
//do another thing
}
}
}
}
Functionally, it doesn't matter, one object doesn't perform better than the other, unless there is shared use of that object by other locking concerns.
With C#, it isn't uncommon to lock on the actual domain object, rather than a surrogate object for the lock. It is also common to see a member object used, and a common legacy example is the SyncRoot object on the early System.Collections. Either way works, as long as you use a reference type.
However, the argument to be made for using an internal surrogate lock object is one of encapsulation. It eliminates the possibility of external interference if a user of your class decides to use your class as a lock. Using an internal lock object protects your locks from external interference, so one could argue that locking is an implementation detail that should be hidden.
The important thing is to ensure it is correct and appropriate. Make sure your locking is done at an appropriate granularity. (For example, using a static lock object probably isn't the best approach for a non-singleton, and probably not even most singletons). In cases where your class has multiple mutually exclusive threaded operations, you don't want to lock on "this" or you have unnecessary contention. That is like having one red light for 2 non-overlapping intersections.

Multi-Threading Question - adding an Element to a static List

Okay, newbie multi-threading question:
I have a Singleton class. The class has a Static List and essentially works like this:
class MyClass {
private static MyClass _instance;
private static List<string> _list;
private static bool IsRecording;
public static void StartRecording() {
_list = new List<string>();
IsRecording = true;
}
public static IEnumerable<string> StopRecording() {
IsRecording = false;
return new List<string>(_list).AsReadOnly();
}
public MyClass GetInstance(){
}
public void DoSomething(){
if(IsRecording) _list.Add("Something");
}
}
Basically a user can call StartRecording() to initialize a List and then all calls to an instance-method may add stuff to the list. However, multiple threads may hold an instance to MyClass, so multiple threads may add entries to the list.
However, both list creation and reading are single operations, so the usual Reader-Writer Problem in multi-threading situations does not apply. The only problem I could see is the insertion order being weird, but that is not a problem.
Can I leave the code as-is, or do I need to take any precautions for multi-threading? I should add that in the real application this is not a List of strings but a List of Custom Objects (so the code is _list.Add(new Object(somedata))), but these objects only hold data, no code besides a call to DateTime.Now.
Edit: Clarifications following some answers: DoSomething cannot be static (the class here is abbreviated, there is a lot of stuff going on that is using instance-variables, but these created by the constructor and then only read).
Is it good enough to do
lock(_list){
_list.Add(something);
}
and
lock(_list){
return new List<string>(_list).AsReadOnly();
}
or do I need some deeper magic?
You certainly must lock the _list. And since you are creating multiple instances for _list you can not lock on _list itself but you should use something like:
private static object _listLock = new object();
As an aside, to follow a few best practices:
DoSomething(), as shown, can be static and so it should be.
for Library classes the recommended pattern is to make static members thread-safe, that would apply to StartRecording(), StopRecording() and DoSomething().
I would also make StopRecording() set _list = null and check it for null in DoSomething().
And before you ask, all this takes so little time that there really are no performance reasons not to do it.
You need to lock the list if multiple threads are adding to it.
A few observations...
Maybe there's a reason not to, but I would suggest making the class static and hence all of its members static. There's no real reason, at least from what you've shown, to require clients of MyClass to call the GetInstance() method just so they can call an instance method, DoSomething() in this case.
I don't see what prevents someone from calling the StartRecording() method multiple times. You might consider putting a check in there so that if it is already recording you don't create a new list, pulling the rug out from everyone's feet.
Finally, when you lock the list, don't do it like this:
static object _sync = new object();
lock(_sync){
_list.Add(new object(somedata));
}
Minimize the amount of time spent inside the lock by moving the new object creation outside of the lock.
static object _sync = new object();
object data = new object(somedata);
lock(_sync){
_list.Add(data);
}
EDIT
You said that DoSomething() cannot be static, but I bet it can. You can still use an object of MyClass inside DoSomething() for any instance-related stuff you have to do. But from a programming usability perspective, don't require the users to MyClass to call GetInstance() first. Consider this:
class MyClass {
private static MyClass _instance;
private static List<string> _list;
private static bool IsRecording;
public static void StartRecording()
{
_list = new List<string>();
IsRecording = true;
}
public static IEnumerable<string> StopRecording()
{
IsRecording = false;
return new List<string>(_list).AsReadOnly();
}
private static MyClass GetInstance() // make this private, not public
{ return _instance; }
public static void DoSomething()
{
// use inst internally to the function to get access to instance variables
MyClass inst = GetInstance();
}
}
Doing this, the users of MyClass can go from
MyClass.GetInstance().DoSomething();
to
MyClass.DoSomething();
.NET collections are not fully thread-safe. From MSDN: "Multiple readers can read the collection with confidence; however, any modification to the collection produces undefined results for all threads that access the collection, including the reader threads." You can follow the suggestions on that MSDN page to make your accesses thread-safe.
One problem that you would probably run into with your current code is if StopRecording is called while some other thread is inside DoSomething. Since creating a new list from an existing one requires enumerating over it, you are likely to run into the old "Collection was modified; enumeration operation may not execute" problem.
The bottom line: practice safe threading!
It's possible, albeit tricky, to write a linked list that allows simultaneous insertions from multiple threads without a lock, but this isn't it. It's just not safe to call _list.Add in parallel and hope for the best. Depending how it's written, you could lose one or both values, or corrupt the entire structure. Just lock it.

C# thread safety of global configuration settings

In a C# app, suppose I have a single global class that contains some configuration items, like so :
public class Options
{
int myConfigInt;
string myConfigString;
..etc.
}
static Options GlobalOptions;
the members of this class will be uses across different threads :
Thread1: GlobalOptions.myConfigString = blah;
while
Thread2: string thingie = GlobalOptions.myConfigString;
Using a lock for access to the GlobalOptions object would also unnecessary block when 2 threads are accessing different members, but on the other hand creating a sync-object for every member seems a bit over the top too.
Also, using a lock on the global options would make my code less nice I think;
if I have to write
string stringiwanttouse;
lock(GlobalOptions)
{
stringiwanttouse = GlobalOptions.myConfigString;
}
everywhere (and is this thread-safe or is stringiwanttouse now just a pointer to myConfigString ? Yeah, I'm new to C#....) instead of
string stringiwanttouse = GlobalOptions.myConfigString;
it makes the code look horrible.
So...
What is the best (and simplest!) way to ensure thread-safety ?
You could wrap the field in question (myConfigString in this case) in a Property, and have code in the Get/Set that uses either a Monitor.Lock or a Mutex. Then, accessing the property only locks that single field, and doesn't lock the whole class.
Edit: adding code
private static object obj = new object(); // only used for locking
public static string MyConfigString {
get {
lock(obj)
{
return myConfigstring;
}
}
set {
lock(obj)
{
myConfigstring = value;
}
}
}
The following was written before the OP's edit:
public static class Options
{
private static int _myConfigInt;
private static string _myConfigString;
private static bool _initialized = false;
private static object _locker = new object();
private static void InitializeIfNeeded()
{
if (!_initialized) {
lock (_locker) {
if (!_initialized) {
ReadConfiguration();
_initalized = true;
}
}
}
}
private static void ReadConfiguration() { // ... }
public static int MyConfigInt {
get {
InitializeIfNeeded();
return _myConfigInt;
}
}
public static string MyConfigString {
get {
InitializeIfNeeded();
return _myConfigstring;
}
}
//..etc.
}
After that edit, I can say that you should do something like the above, and only set configuration in one place - the configuration class. That way, it will be the only class modifying the configuration at runtime, and only when a configuration option is to be retrieved.
Your configurations may be 'global', but they should not be exposed as a global variable. If configurations don't change, they should be used to construct the objects that need the information - either manually or through a factory object. If they can change, then an object that watches the configuration file/database/whatever and implements the Observer pattern should be used.
Global variables (even those that happen to be a class instance) are a Bad Thing™
What do you mean by thread safety here? It's not the global object that needs to be thread safe, it is the accessing code. If two threads write to a member variable near the same instant, one of them will "win", but is that a problem? If your client code depends on the global value staying constant until it is done with some unit of processing, then you will need to create a synchronization object for each property that needs to be locked. There isn't any great way around that. You could just cache a local copy of the value to avoid problems, but the applicability of that fix will depend on your circumstances. Also, I wouldn't create a synch object for each property by default, but instead as you realize you will need it.

Categories

Resources