Is static constructor really thread safe? - c#

My code:
using System;
using System.Diagnostics;
using System.Threading.Tasks;
public class Program
{
private static void Main(string[] args)
{
var test = new Test(); // TypeInitializationException?
var test2 = new Test();
}
public class Test
{
public Test()
{
Trace.WriteLine("Test Created");
}
static Test()
{
Task.Factory.StartNew(
() =>
{
throw new Exception();
});
}
}
}
If I change the static const to :
static Test()
{
throw new Exception();
}
Then it is throwing TypeInitializationException! I thought static constructor is thread safe?
Is the C# static constructor thread safe?
private static void Main(string[] args)
{
Task.Factory.StartNew(
() =>
{
var test = new Test();
});
var test2 = new Test(); // HERE I GET THE EXCEPTION!!!!
}
public class Test
{
public Test()
{
Trace.WriteLine("Test Created");
}
static Test()
{
throw new Exception();
}
}
}

Thread safe is not a particularly helpful phrase to use. You should generally avoid using it as it doesn't really tell you what operations are and are not safe.
Instead it's important to specifically state what thread-related operations and situations are supported in any given context. One can then objectively and clearly state whether the expectations are violated.
C# will ensure that static constructors are run at some point before they are used, no matter how many threads might use the class, or whether another thread is currently running the static constructor.
C# will ensure that it doesn't run the static constructor more than once, no matter how many different threads might be using the same class at around the same time, or whether another thread uses a class while it is currently being initialized.
The specs specifically state that if a static constructor throws an exception in the one time that it runs then all future uses of that type will throw a TypeInitializationException, which is what you are seeing.
The behavior that you are seeing is entirely in line with the behavior defined in the specifications.

Thread-safe in this context only means that you don't need to worry about two threads invoking the static constructor at the same time, or one thread starting the static constructor, and a second thread thinking it has run and skipping the constructor, even though it hasn't finished (causing access to uninitialized fields).
If you throw an exception in the constructor, that is simply an error. Nothing to do with thread safety. Type initialization errors are very bad, and will keep happening until the static constructor can successfully complete.

Static constructor wraps all exceptions which are thrown inside into TypeInitializationException and that doesn't have relation to thread safety.
It is guaranteed that constructor is executed once and only once, before first usage of a type (or no execution if type isn't used) not depending on how many threads access the type. This means it is thread safe.

Related

Is the following C# Code Thread-safe in a multi-threaded evironment?

Since I create the readonly static instance as soon as someone uses the class, no lazy loading, this code is thread safe and I do not need to follow the Double-checked locking design pattern, correct?
public class BusSingleton<T> where T : IEmpireEndpointConfig, new()
{
private static readonly BusSingleton<T> instance = new BusSingleton<T>();
private IBus bus;
public IBus Bus
{
get { return this.bus; }
}
public static BusSingleton<T> Instance
{
get
{
return instance;
}
}
private BusSingleton()
{
T config = new T();
bus = NServiceBus.Bus.Create(config.CreateConfiguration());
((IStartableBus) bus).Start();
}
}
During the static initializer the run-time puts a lock around the object's type so two instances of the initializer can not be run at the same time.
The only thing you must be careful of is if NServiceBus.Bus.Create, config.CreateConfiguration, or bus.Start() use multiple threads internally and try to access your object's type anywhere within the class/function on that other thread you could deadlock yourself if one of those three function calls does not return until after that internal thread is done.
When you do the traditional "lazy singleton" with double checked locking the static initializer will have already finished and you don't run the risk of deadlocking yourself.
So if you are confidant that those 3 functions will not try to access your type on another thread then it is fine to not use double checked locking for your use case.
That looks safe as long as you don't need to delay the instantiation to run initalization code or anything like that. Which it sounds like you don't need.
https://msdn.microsoft.com/en-us/library/ff650316.aspx

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.

Calling method after destructor runs

I've readed about this, but I forgot, where I saw an example. So it looks like this
public class Program
{
private static void Main()
{
new SomeClass(10).Foo();
}
}
public class SomeClass
{
public int I;
public SomeClass(int input)
{
I = input;
Console.WriteLine("I = {0}", I);
}
~SomeClass()
{
Console.WriteLine("deleted");
}
public void Foo()
{
Thread.Sleep(2000);
Console.WriteLine("Foo");
}
}
so output should be:
I = 10
deleted
Foo
why? due to optimizer. It sees that method doesn't use any field so it can destroy an object before the method is called. So why it doesn't do it?
I'l post an example if i found it.
so i found the source. Pro .NET Performance: Sasha Goldshtein , Dima Zurbalev , Ido Flatow
Another problem has to do with the asynchronous nature of finalization
which occurs in a dedicated thread. A finalizer might attempt to
acquire a lock that is held by the application code, and the
application might be waiting for finalization to complete by calling
GC.WaitForPendingFinalizers(). The only way to resolve this issue is
to acquire the lock with a timeout and fail gracefully if it can’t be
acquired. Yet another scenario is caused by the garbage collector’s
eagerness to reclaim memory as soon as possible. Consider the
following code which represents a naïve implementation of a File class
with a finalizer that closes the file handle:
class File3
{
Handle handle;
public File3(string filename)
{
handle = new Handle(filename);
}
public byte[] Read(int bytes)
{
return Util.InternalRead(handle, bytes);
}
~File3()
{
handle.Close();
}
}
class Program
{
static void Main()
{
File3 file = new File3("File.txt");
byte[] data = file.Read(100);
Console.WriteLine(Encoding.ASCII.GetString(data));
}
}
This innocent piece of code can break in a very nasty manner. The Read
method can take a long time to complete, and it only uses the handle
contained within the object, and not the object itself. The rules for
determining when a local variable is considered an active root dictate
that the local variable held by the client is no longer relevant after
the call to Read has been dispatched. Therefore, the object is
considered eligible for garbage collection and its finalizer might
execute before the Read method returns! If this happens, we might be
closing the handle while it is being used, or just before it is used.
but i can't reproduce this behaviour
public void Foo()
{
Thread.Sleep(1000);
Console.WriteLine("Foo");
}
Methods that don't use any instance member of a class should be declared static. Which has several advantages, it is for one very helpful to a reader of the code. It unambiguously states that a method doesn't mutate the object state.
And for another has the great advantage that you'll now understand why there's no discrepancy in seeing the method running after the object got finalized. The GC just doesn't have any reason to keep this alive, there are no references left to the object when Foo() starts executing. So no trouble at all getting it collected and finalized.
You'll find more background info on how the jitter reports object references to the garbage collector in this answer.
Anyway, i found the way to reproduce it, i just should read more attentive :) :
public class Program
{
private static void Main()
{
new Thread(() =>
{
Thread.Sleep(100);
GC.Collect();
}).Start();
new SomeClass(10).Foo();
}
}
public class SomeClass
{
public int I;
public SomeClass(int input)
{
I = input;
Console.WriteLine("I = {0}", I);
}
~SomeClass()
{
Console.WriteLine("deleted");
}
public void Foo()
{
Thread.Sleep(1000);
Console.WriteLine("Foo");
}
}
so in this case destructor will be called before Foo method.
The problem is because you're using threading in Foo. You tell the code to wait for 1 second, but you don't tell it to wait for the second to be up before executing everything else. Therefore the original thread executes the destructor before Foo finishes.
A better way of writing Foo would be something like this:
public void Foo()
{
var mre = new ManualResetEvent(false);
mre.WaitOne(1000);
Console.WriteLine("Foo");
}
Using the ManualResetEvent will force the code to completely pause until, in this case, the timeout is hit. After which the code will continue.

Static method, static field and multitheading in C#

I have 1 static class and 1 field and 2 methods within it:
static class MyClass{
private static HttpClient client = new HttpClient();
private static string SendRequestToServer(int id)
{
Task<HttpResponseMessage> response = client.GetAsync("some string");
responseTask.ContinueWith(x => PrintResult(x));
return "some new value";
}
private static void Print(Task<HttpResponseMessage> task)
{
Task<string> r = task.Result.Content.ReadAsStringAsync();
r.ContinueWith(resultTask => Console.WriteLine("result is: " + resultTask.Result));
}
}
The question is, if many threads start using MyClass and its methods, would it cause some problems?
All the resources accessed through these methods need to be thread-safe. In your case, they are not. If you look at the HttpClient documentation, it states:
Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.
You're calling an instance method (client.GetAsync), which is not be guaranteed to be thread-safe, so that could potentially cause problems for you.
To mitigate this, you could:
create a new (local) HttpClient on each call.
synchronize access to client (e.g. using a lock).
Also, I can't tell you if PrintResult will be thread-safe, but Console.WriteLine should be thread-safe.
You are likely to expect unpredictable results with such setup.You need to have threads access the data in a synchronized manner.A lock statement need to used in your case to make sure the execution happens in a synchronized and stable manner.
private static Object locker= new Object();
private static string SendRequestToServer(int id)
{
lock(locker)
{
Task<HttpResponseMessage> response = client.GetAsync("some string");
responseTask.ContinueWith(x => PrintResult(x));
return "some new value";
}
}

Potential pitfalls with static constructors in C#

My question comes after refactoring a class that contained only static methods to be declared as a static class, and experiencing weird issues when starting the application.
I have not performed any thorough investigation but it seems that some call being made from within the static constructor does not complete for some reason.
So, I would like to know where there are any pitfalls when using static constructors in C#? More specifically, are there any things that should be avoided at all cost and not be used from within the static constructor?
There are several pitfalls to static constructors. For example, if a static constructor throws an exception, you would continue getting a TypeInitializationException whenever you access any of its members.
If a static constructor throws an exception, the runtime will not invoke it a second time, and the type will remain uninitialized for the lifetime of the application domain in which your program is running.
In general, static classes should only be used in stateless scenarios where you won’t need any initialization. If your class needs to be initialized, you might be better off using the singleton pattern, which can be lazily initialized on first access:
public class MyClass
{
private static readonly Lazy<MyClass> current =
new Lazy<MyClass>(() => new MyClass());
public static MyClass Current
{
get { return current.Value; }
}
private MyClass()
{
// Initialization goes here.
}
public void Foo()
{
// ...
}
public void Bar()
{
// ...
}
}
static void Main(string[] args)
{
MyClass.Current.Foo(); // Initialization only performed here.
MyClass.Current.Bar();
MyClass.Current.Foo();
}
Edit: I did some further reading up on the matter, and it appears that static constructors do cause deadlocks if you perform blocking operations (e.g. asynchronous callbacks or thread synchronization) within them.
The CLR internally uses locking to prevent type initializers (static constructors) from being executed multiple times concurrently. Thus, if your static constructor attempts to access another member of its declaring type from another thread, it would inevitably deadlock. Since “another member” could be an anonymous function declared as part of a PLINQ or TPL operation, these bugs can be subtle and hard to identify.
Igor Ostrovsky (MSFT) explains this in his Static constructor deadlocks article, providing the following example of a deadlock:
using System.Threading;
class MyClass
{
static void Main() { /* Won’t run... the static constructor deadlocks */ }
static MyClass()
{
Thread thread = new Thread(arg => { });
thread.Start();
thread.Join();
}
}
In the above example, the new thread needs to access the empty anonymous function, { }, defined as its callback. However, since the anonymous function is compiled as another private method of MyClass behind the scenes, the new thread cannot access it before the MyClass type initializes. And, since the MyClass static constructor needs to wait for the new thread to complete first (because of thread.Join()), a deadlock ensues.
Yes, there are some pitfalls, mostly related to when the class is initialized. Basically, a class with a static constructor will not be marked with the beforefieldinit flag, which allows the runtime to initialize it at a later time.
Have a look at this article for more details.
This is not an answer to the question, but it's too long for a comment, so I offer it here...
Since I didn't know for static class construct, I have used following scheme (simplified) to provide me with singletons:
public class SomeSingleton {
static _instance;
static public SomeSingleton Instance {
get {
if (_instance==null) {
_instance=new SomeSingleton();
}
return _instance;
}
}
}
Later, you use
SomeSingleton.Instance.MyProp = 3;
And first usage of the Instance member will construct your singleton.
I guess that it is OK since instantiation of the singletons if there are many of such classes is done in proper order.

Categories

Resources