i have the following static class with generic methods and i'm wondering if it's safe to use it from different threads and with different objects? i'm not sure how this works below the covers so an explanation of would help
public static class Serialization
{
public static byte[] Serialize<T>(T obj)
{
using (var ms = new MemoryStream())
{
Serializer.SerializeWithLengthPrefix<T>(ms, obj, PrefixStyle.Base128);
return ms.ToArray();
}
}
public static T DeSerialize<T>(byte[] bytes)
{
using (var ms = new MemoryStream(bytes))
{
return Serializer.DeserializeWithLengthPrefix<T>(ms, PrefixStyle.Base128);
}
}
}
The only problem with threads is accessing the same object from different threads without synchronization.
If each function only uses parameters for reading and local variables, they don't need any synchronization to be thread-safe.
It follows the convention that static methods should be thread-safe, but actually in v2 that static api is a proxy to an instance method on a default instance: in the case protobuf-net, it internally minimises contention points, and synchronises the internal state when necessary. Basically the library goes out of its way to do things right so that you can have simple code.
Related
I have an ASP.Net site that consumes ASP.Net XML webservices. To communicate with each webmethod in the webservice I have a static class with static business methods, one for each webmethod in the webservice. The static business methods create a new instance of the webreference class each time they are called. The new instance of the webreference class is used to only call the webmethod, none of the properties in the instance of the webreference are changed from their defaults.
My question is can I create just a global static instance of the webreference class to use by all of the static business methods instead of creating a new one each time a static business method is called? (Basically are instances of a webreference class thread safe?)
My concern here is that the instance of the webreference class has some properties that are not thread safe and since the code is for a web site, multiple threads calling the same static business methods at the same time would cause issues between the threads.
The reason I'm asking is to try and find additional changes I can make to increase the site's performance. In tracing the site's performance I see a fair amount of time being spent on creating an instance of the webreference class. Additionally based on the garbage collection counters I'm seeing a lot of time being spent there too.
Example Code:
This is what I'm currently doing
public static class WebMethodWrapper
{
public static bool CallMethodA(string p1)
{
using(com.mysite.service1 _provider = new com.mysite.service1())
{
return(_provider.WebMethodA(p1));
}
}
public static bool CallMethodB(string p1)
{
using(com.mysite.service1 _provider = new com.mysite.service1())
{
return(_provider.WebMethodB(p1));
}
}
}
This is what I'd like to do
public static class WebMethodWrapper
{
static com.mysite.service1 _Provider = null;
static WebMethodWrapper()
{
_Provider = new com.mysite.service1();
}
public static bool CallMethodA(string p1)
{
return(_Provider.WebMethodA(p1));
}
public static bool CallMethodB(string p1)
{
return(_Provider.WebMethodB(p1));
}
}
My question is can I create just a global static instance of the webreference class to use by all of the static business methods instead of creating a new one each time a static business method is called? (Basically are instances of a webreference class thread safe?)
My concern here is that the instance of the webreference class has some properties that are not thread safe and since the code is for a web site, multiple threads calling the same static business methods at the same time would cause issues between the threads.
A jolly good question to which it seems you are well on the way to answering. I agree you should probably stick with your current approach where each static method creates its own local copy of the service client. This encourages thread-safety not only from the point of view of the client, but also guarantees that remote calls to the service are done so using unique proxies - where results are not potentially multiplexed with other requests.
If you went down the other route of using a shared instance, then you have to take into consideration those scenarios where the service faults in one thread.
Maybe there was a timeout?
Maybe some remote business logic failed?
Maybe the network failed because your room-mate is downloading the latest episode of Game of Thrones exceeding your download quota?
You would then need to invalidate that client and recreate a new one. All of this would need to be safely thread-locked. It sort of becomes quite complex to manage this orchestration.
Let's consider your alternative code:
public static bool CallMethodA(string p1)
{
return(_Provider.WebMethodA(p1));
}
Let's say this was successfully called the first time. Now imagine you need to call this 5 mins 5 seconds later but sadly by this time the server has severed the connection because it has a timeout of 5 mins. Your second call faults. The above code would need to be adjusted to allow for those scenarios. In our simple example below we recreate the client during a failure and try once more.
Perhaps:
public static class WebMethodWrapper
{
static com.mysite.service1 _Provider = null;
static object _locker = new object();
static WebMethodWrapper()
{
_Provider = new com.mysite.service1();
}
static com.mysite.service1 Client
{
get
{
lock (_locker)
{
return _Provider;
}
}
}
public static bool CallMethodA(string p1)
{
try
{
return (Client.WebMethodA(p1));
}
catch (Exception ex) // normally just catch the exceptions of interest
{
// Excercise for reader - use a single method instead of repeating the below
// recreate
var c = RecreateProxy();
// try once more.
return (c.WebMethodA(p1));
}
}
public static bool CallMethodB(string p1)
{
try
{
return (Client.WebMethodB(p1));
}
catch (Exception ex) // normally just catch the exceptions of interest
{
// Excercise for reader - use a single method instead of repeating the below
// recreate
var c = RecreateProxy();
// try once more.
return (c.WebMethodB(p1));
}
}
static com.mysite.service1 RecreateProxy()
{
lock (_locker)
{
_Provider = new com.mysite.service1();
return _Provider;
}
}
}
All of this could be wrapped-up in some generic service client cache that could maintain a collection of ready-to-go clients in a connection pool? Maybe a background thread periodically pings each client to keep them alive? An exercise for the reader perhaps.
Then again, sharing the same proxy instance between threads may not be a good idea from the service point of view, unless your service is marked as per-call which may or may not impact your design or performance.
Conclusion
Your current code is arguably safer and less complex.
Good luck!
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.
I think I've developed a cargo-cult programming habit:
Whenever I need to make a class threadsafe, such as a class that has a Dictionary or List (that is entirely encapsulated: never accessed directly and modified only by member methods of my class) I create two objects, like so:
public static class Recorder {
private static readonly Object _devicesLock = new Object();
private static readonly Dictionary<String,DeviceRecordings> _devices;
static Recorder() {
_devices = new Dictionary<String,DeviceRecordings>();
WaveInCapabilities[] devices = AudioManager.GetInDevices();
foreach(WaveInCapabilities device in devices) {
_devices.Add( device.ProductName, new DeviceRecordings( device.ProductName ) );
}
}//cctor
// For now, only support a single device.
public static DeviceRecordings GetRecordings(String deviceName) {
lock( _devicesLock ) {
if( !_devices.ContainsKey( deviceName ) ) {
return null;
}
return _devices[ deviceName ];
}
}//GetRecordings
}//class
In this case, I wrap all operations on _devices within a lock( _devicesLock ) { block. I'm beginning to wonder if this is necessary. Why don't I just lock on the dictionary directly?
In your use case, locking the dictionary will be fine, since it is private. You still need to carefully design your class to prevent deadlocks.
If the dictionary is the only shared resource that needs thread safety and other parts of your code are thread-safe, I'd recommend using the ConcurrentDictionary instead of locking.
It is not needed if you are sure that the main object is used completely within the class. Strictly speaking it is not necessary even if it is but version with 2 variable is much easier to reason about:
whoever reads code does not need to think about if the main object is ever exposed and potentially locked by something outised your class
the code with separate object for locking looks more in line with good practice
will be safer if one accidentally/intentionally exposes the main object
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.
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.