Static method, static field and multitheading in C# - 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";
}
}

Related

Disposing thread static variable

I have a ThreadStatic member in a static class. The static class is used in a multi threaded environment. I want to make sure that when a thread is returned to threadpool (or re-used), the member is disposed (or re-initialized), so any subsequent uses of the particular thread gets a fresh copy of the variable. The member has to stay static so an instance member will not really help.
I have tried using ThreadLocal, AsyncLocal and CallContext but none of these really help. (CallContext is mostly for proof of concept, its a .net standard app so callcontext won't work anyways).
This is just a sample code I wrote to recreate my problem having ThreadStatic, ThreadLocal, AsyncLocal and CallContext for testing.
class Program
{
static void Main(string[] args)
{
var act = new List<Action<int>>()
{
v=> ThreadClass.Write(v),
v=> ThreadClass.Write(v),
};
Parallel.ForEach(act, new ParallelOptions { MaxDegreeOfParallelism = 1 }, (val, _, index) => val((int)index));
Console.WriteLine($"Main: ThreadId: {Thread.CurrentThread.ManagedThreadId} ThreadStatic = {ThreadClass.ThreadStatic} ThreadLocal = {ThreadClass.ThreadLocal.Value} AsyncLocal = {ThreadClass.AsyncLocal.Value} CallContext: {ThreadClass.CallContextData}");
Console.ReadKey();
}
}
public static class ThreadClass
{
static object _lock = new object();
[ThreadStatic]
public static string ThreadStatic;
public static ThreadLocal<string> ThreadLocal = new ThreadLocal<string>(() => "default");
public static readonly AsyncLocal<string> AsyncLocal = new AsyncLocal<string>();
public static string CallContextData
{
get => CallContext.LogicalGetData("value") as string;
set => CallContext.LogicalSetData("value", value);
}
static ThreadClass()
{
AsyncLocal.Value = "default";
}
public static void Write(int id)
{
lock (_lock)
{
Console.WriteLine($"{id} Init: ThreadId: {Thread.CurrentThread.ManagedThreadId} ThreadStatic = {ThreadStatic} ThreadLocal = {ThreadLocal.Value} AsyncLocal = {AsyncLocal.Value} CallContext: {ThreadClass.CallContextData}");
ThreadStatic = $"Static({id})";
ThreadLocal.Value = $"Local({id})";
AsyncLocal.Value = $"Async({id})";
CallContextData = $"Call({id})";
Console.WriteLine($"{id} Chng: ThreadId: {Thread.CurrentThread.ManagedThreadId} ThreadStatic = {ThreadStatic} ThreadLocal = {ThreadLocal.Value} AsyncLocal = {AsyncLocal.Value} CallContext: {ThreadClass.CallContextData}");
}
}
}
The above code is run in a single thread so the thread can be re-used.
0 Init: ThreadId: 1 ThreadStatic = ThreadLocal = default AsyncLocal = default CallContext:
0 Chng: ThreadId: 1 ThreadStatic = Static(0) ThreadLocal = Local(0) AsyncLocal = Async(0) CallContext: Call(0)
--------------------
1 Init: ThreadId: 1 ThreadStatic = Static(0) ThreadLocal = Local(0) AsyncLocal = Async(0) CallContext: Call(0)
1 Chng: ThreadId: 1 ThreadStatic = Static(1) ThreadLocal = Local(1) AsyncLocal = Async(1) CallContext: Call(1)
--------------------
Main: ThreadId: 1 ThreadStatic = Static(1) ThreadLocal = Local(1) AsyncLocal = CallContext:
However, as seen in the output, when the second call is made and thread 1 is reused, it still has the values set by thread 0.
Is there any way to reset ThreadStatic variable to default value or null when thread is re used?
TL;DR
If don't want a variable reused by multiple threads in a multi-threaded application, there's no reason to make it static.
If we don't want a variable reused by the same thread, it's questionable why we would deliberately use [ThreadStatic], since that's what it allows us to do.
I'm focusing on the ThreadStatic aspect of this since it seems to be a focus of the question.
so any subsequent uses of the particular thread gets a fresh copy of the variable.
Uses of the thread don't need their own copy of the variable - methods that use the variable may or may not need their own copy of the variable. That sounds like a hair-splitting thing to say, but a thread, by itself, doesn't need a copy of any variable. It could be doing things unrelated to this static class and this variable.
It's when we use the variable that we care whether it is a "fresh copy." That is, when we invoke a method that uses the variable.
If, when we use the static variable (which is declared outside of a method), what we want is to ensure that it's newly instantiated before we use it and disposed when we're done with it, then we can accomplish that within the method that uses it. We can instantiate it, dispose it, even set it to null if we want to. What becomes apparent as we do this, however, is that it usually eliminates any need for the variable to be declared outside the method that uses it.
If we do this:
public static class HasDisposableThreadStaticThing
{
[ThreadStatic]
public static DisposableThing Foo;
public static void UseDisposableThing()
{
try
{
using (Foo = new DisposableThing())
{
Foo.DoSomething();
}
}
finally
{
Foo = null;
}
}
}
We've accomplished the goal.
Is there any way to reset ThreadStatic variable to default value or null when thread is re used?
Done. Every time the same thread enters the method ("the thread is re used") it's null.
But if that's what we want, then why not just do this?
public static class HasDisposableThreadStaticThing
{
public static void UseDisposableThing()
{
using (var foo = new DisposableThing())
{
foo.DoSomething();
}
}
}
The result is exactly the same. Every thread starts with a new instance of DisposableThing because when it executes the method it declares the variable and creates a new instance. Instead of setting it to null the reference goes out of scope.
The only difference between the two is that in the first example, DisposableThing is publicly exposed outside of the class. That means that other threads could use it instead of declaring their own variable, which is weird. Since they would also need to make sure it's instantiated before using it, why wouldn't they also just create their own instance as in the second example?
The easiest and most normal way to ensure that a variable is initialized and disposed every time it's needed in a static method is to declare that variable locally within the static method and create a new instance. Then regardless of how many threads call it concurrently they will each use a separate instance.
Unfortunately, ThreadPool does not provide an API to listen to repool events to do this universally. However, if you have control over every place that queues work to the ThreadPool, you can write a simple wrapper to do what you want.
public struct DisposableThreadStatic<T> : IDisposable where T : class, IDisposable
{
[ThreadStatic]
private static T ts_value;
private bool _shouldDispose;
public T Value => ts_value;
public static DisposableThreadStatic<T> GetOrCreate(Func<T> creator)
{
if (ts_value == null)
{
ts_value = creator();
return new DisposableThreadStatic<T>() { _shouldDispose = true };
}
return default;
}
public void Dispose()
{
if (_shouldDispose && ts_value != null)
{
ts_value.Dispose();
ts_value = null;
}
}
}
With this, you can wrap your threaded function with this.
ThreadPool.QueueUserWorkItem(_ =>
{
using var dts = DisposableThreadStatic<MyDisposable>.GetOrCreate(() => new MyDisposable());
// Use value, call any other functions, etc.
dts.Value.Func();
});
And using that same GetOrCreate call anywhere deeper in the call stack will just return the cached value, and only the top-most call (when the work completes) will dispose it.

Is static constructor really thread safe?

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.

Singleton Class which requires some async call

I have a Singleton Class which loads some data on its construction. The problem is that loading this data requires calling async methods, but the constructor cannot be async.
In other words, my class has following structure:
public class Singleton
{
private static Singleton instance;
private Singleton()
{
LoadData();
}
public static Singleton Instance
{
get
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
}
LoadData() is an async function which calls lots of async functions as well as initialization.
How can I call LoadData() properly so everything initialize correctly?
The solution for a thread-safe, async singleton is actually super simple, if we only let the inner mechanisms of the Task class work for us!
So, how does a Task work? Let’s say you have an instance of a Task<T> and you await it once. Now the task is executed, and a value of T is produced and returned to you. What if you await the same task instance again? In this case the task just returns the previously produced value immediately in a completely synchronous manner.
And what if you await the same task instance simultaneously from multiple threads (where you would normally get a race condition)? Well, the first one (since there will be one that gets there first) will execute the task code while the others will wait for the result to be processed. Then when the result has been produced, all the await’s will finish (virtually) simultaneously and return the value.
So the solution for an async singleton that is thread-safe is actually super simple:
public class Singleton
{
private static readonly Task<Singleton> _getInstanceTask = CreateSingleton();
public static Task<Singleton> Instance
{
get { return _getInstanceTask; }
}
private Singleton(SomeData someData)
{
SomeData = someData;
}
public SomeData SomeData { get; private set; }
private static async Task<Singleton> CreateSingleton()
{
SomeData someData = await LoadData();
return new Singleton(someData);
}
}
Now you can access the singleton this way:
Singleton mySingleton = await Singleton.Instance;
or
Singleton mySingleton = Singleton.Instance.Result;
or
SomeData mySingletonData = (await Singleton.Instance).SomeData;
or
SomeData mySingletonData = Singleton.Instance.Result.SomeData;
Read more here: Async singleton initialization
The problem is that loading this data requires calling async methods, but the constructor cannot be async.
While you can't make the constructor itself asynchronous, you can call asynchronous methods from within the constructor. You just will not get the results back immediately.
Provided the asynchronous methods return Task or Task<T>, you can always use a continuation on the task to set your data within the class once the asynchronous operation completes, or just block on the results, depending on what makes the most sense in your scenario. Without knowing the requirements for construction of this object, it's difficult to know what is appropriate in this scenario.
Edit:
One option, given the goals listed above, would be to change your Singleton declaration so that method to retrieve the Instance was a method, not a property. This would allow you to make it asynchronous:
public class Singleton
{
private static Singleton instance;
private Singleton()
{
// Don't load the data here - will be called separately
}
public static async Task<Singleton> GetInstance()
{
if (instance == null)
{
instance = new Singleton();
await instance.LoadData();
}
return instance;
}
}
This would allow you to use await on the call to actually retrieve the instance. The nice thing about this is that it does make it very clear that you're calling an asynchronous operation, and you will get proper handling of the results, as the result will come back like any other async method.
Be aware, however, that this isn't thread safe (though the original wasn't either), so if you're going to use this Singleton from multiple threads, you may have to rethink the overall design.
The other option would be to make your Singleton class not automatically load data. Make the methods that retrieve the data from the class asynchronous, instead. This provides some real advantages, as the usage is probably a bit more standard, and you can support calls from multiple threads a bit more easily (since you can control the data loading process) than you'd be able to handle it with making the access of the class instance asynchronous.
You can use asynchronous lazy initialization for this:
public class Singleton
{
private static readonly AsyncLazy<Singleton> instance =
new AsyncLazy<Singleton>(CreateAndLoadData);
private Singleton()
{
}
// This method could also be an async lambda passed to the AsyncLazy constructor.
private static async Task<Singleton> CreateAndLoadData()
{
var ret = new Singleton();
await ret.LoadDataAsync();
return ret;
}
public static AsyncLazy<Singleton> Instance
{
get { return instance; }
}
}
And then you can use it like this:
Singleton singleton = await Singleton.Instance;
One benefit of using AsyncLazy<T> is that it is threadsafe. However, be aware that it always executes its delegate on a thread pool thread.
Well, it doesn't make much sense that you want asynchronously initialize a singleton. If you simply want to call an method that returns Task in your initialization, you can simply do:
var task = MyAsyncMethod();
task.Wait();
return task.Result;
Without the need to make the method async.
But, if what you want is for the singleton value to be a task, you can use Lazy as such:
Lazy<Task<int>> l = new Lazy<Task<int>>(async () => { int i = await calculateNumber(); return i; });
In addition, Lazy<T> is the preferred method for implementing "singletons". Singleton classes are hard to get right (or hard to keep right)...

Multithreading, generic locks

I have a singleton class which looks a lot like this,
public class CfgHandler
{
private static readonly string ConfigDir = "Config";
public T Get<T>() where T : class, new()
{
string cfgFile = Path.Combine(ConfigDir, typeof(T).FullName + ".json");
if (File.Exists(cfgFile))
{
var reader = new JsonReader();
return reader.Read<T>(File.ReadAllText(cfgFile));
}
return null;
}
public void Set<T>(T instance) where T : class, new()
{
string cfgFile = Path.Combine(ConfigDir, typeof(T).FullName + ".json");
var writer = new JsonWriter();
string json = writer.Write(instance);
File.WriteAllText(cfgFile, json);
}
}
The class is used in a multithreaded environment and I want to add locks. But not one lock for the whole class, since I don't want a race condition between cfg.Set<Foo>(); and cfg.Set<Bar>() as they work with different data.
I've thought about adding the following class to CfgHandler,
private static class Locks<T>
{
private static object _lock = new object();
public static object Lock { get { return _lock; } }
}
and then lock like this (both for Get and Set),
public void Set<T>(T instance) where T : class, new()
{
lock(Locks<T>.Lock)
{
// save to disk
}
}
Am I missing something trivial? Is there a better way of achieving my goal?
Lock per instance or lock per type?
The way you are doing it (with a static Locks<T>.Lock) means that every call to Set<Foo> even on a different instance of CfgHandler will share the same lock. Is that what you want? I'm guessing you may be better off just locking per instance - it will save you the complexity of Locks<T>. Just declare a private instance member (private object _lock = new object();) and use it (lock(this._lock))
EDIT If you're using a singleton instance of CfgHandler and want to lock per type, then I guess your approach is perfectly fine. If you're not using a single instance, but still want to lock per type then just make sure to use an instance of Locks<T> instead of making it static.
Please see my question here for more details: Are static members of generic classes shared between types
The implementation you have is simple but effective, it will prevent concurrent access to the Set<T>(T Instance) call correctly. My only advice is that the lock duration should be limited if you are making many concurrent calls to this API. For instance you could do all the work, but then only lock the call to the writer.write(instance) call, which is the only non-threadsafe work you appear to be doing in the call.
As an aside you have the potential to improve your code on the Get call, please see my answer here Is there a way to check if a file is in use? regarding your check for the file existing.

Are these private static members thread safe?

I have the following code with private static members.
All of these classes say that they are thread safe in the MSDN library for "public static" members.
My question is whether these members will be thread safe when used as private static instead of "public static" as stated in the MSDN library.
public static class passwordManager
{
private static System.Security.Cryptography.SHA256 shaM = new System.Security.Cryptography.SHA256Managed();
private static System.Security.Cryptography.RandomNumberGenerator rand = new System.Security.Cryptography.RNGCryptoServiceProvider();
private static System.Text.Encoding enc = System.Text.Encoding.ASCII;
public static string produceSalt(int size)
{
byte[] by = new byte[size];
lock (rand)
{
rand.GetBytes(by);
}
return enc.GetString(by, 0, by.Length);
}
public static string encryptPassword(string password, string salt){
return enc.GetString(shaM.ComputeHash(enc.GetBytes(password + salt)));
}
public static bool isCorrectPassword(string inputPassword, string DBsalt, string DBpassword)
{
return encryptPassword(inputPassword, DBsalt) == DBpassword;
}
This might be entirely dependent on whether the methods I am using themselves use shared variables instead of all method instance variables... some peace of mind would be helpful but I would rather not have to lock everything here if it isn't necessary.
The only reason I locked the random number generator is to limit the possibility of getting the same salt however the chances of this being called by two threads at the same time is very low in my situation.
Thanks,
Mike
This should now be thread safe. I was trying to save on object instantiation overhead but I guess there is a trade off between this and lock waiting. On a high load system lock waiting would likely greatly overpower instantiation overhead and memory usage.
public static class passwordManager
{
private static System.Security.Cryptography.RandomNumberGenerator rand = new System.Security.Cryptography.RNGCryptoServiceProvider();
public static byte[] produceSalt(int size)
{
byte[] by = new byte[size];
lock (rand)
{
rand.GetBytes(by);
}
return by;
}
public static byte[] encryptPassword(string password, byte[] salt){
System.Security.Cryptography.SHA256 shaM = new System.Security.Cryptography.SHA256Managed();
System.Text.Encoding enc = new System.Text.UTF8Encoding();
return shaM.ComputeHash(concatArrays(enc.GetBytes(password), salt));
}
public static bool isCorrectPassword(string inputPassword, byte[] DBsalt, byte[] DBpassword)
{
return compare(encryptPassword(inputPassword, DBsalt), DBpassword);
}
}
Your code is not thread-safe.
Consider the System.Text.Encoding variable enc. You are calling GetString which is an instance member. The documentation says that only public static members are thread-safe so by inference GetString is not thread-safe because it is not a public static member.1
This code may fail due to the following reasons:
You have made no attempt to synchronize access to Encoding.GetString.
Encoding.GetString is called from a public static method in your passwordManager class.
Public static methods have a high probability of being executed by multiple threads simultaneously.
The reason why public static methods are almost always designed to be thread-safe is because it would be awkward for the caller to always synchronize access to it. You cannot limit multithreaded access to static members like you can with instance members. Consider an ASP.NET application, for example. Web page requests are frequently handled concurrently on separate threads. Do you want to use a lock everytime you call a static method? Of course not. This is a ridiculous burden to place on a developer.
Update:
Your new code is now thread-safe. You will have to do some benchmark tests to see which way is faster: using a lock or instantiating new instances on every call like you have now. I would not be surprised if the lock were faster.
1The same could be said for shaM.ComputeHash and enc.GetBytes.
thread safety won't depend on whether something is private or public.
BTW, thread safety document says any public static members of this type, not when this type is embedded as public static.
In short you have to lock your fields like sham, if you are multi-threading.
You might be better off creating method level variables instead of trying to make synchronise access to shared private fields. That way you will still achieve concurrency as each thread has it's own call stack so will have separate instances of each object and thus allow multiple threads to execute the method simultaneously. If you lock on a shared object then only one thread can execute the method at a time. Another option may be to use the [ThreadStatic] attribute on each field so they will not be shared across threads.

Categories

Resources