should c# static getter be thread safe - c#

I am wondering if this class is thread safe
Can I access the Currencies property's getter without performing a lock?
Should I lock my access to the Currencies property within the GetLiveExchangeRates() method?
public class CurrencyManager
{
public static List<CurrencyModel> Currencies { get; private set; }
private static readonly object LockObj = new object();
public CurrencyManager()
{
Currencies = new List<CurrencyModel>();
}
public static void GetLiveExchangeRates()
{
lock (LockObj)
{
Currencies = GetSomeFooLiveDataFromInternet();
}
}
}
EDIT
How would you refactor it?

If you must stick with a static class, I would refactor the class like this:
public class CurrencyManager
{
private static readonly IEnumerable<CurrencyModel> currencies = Enumerable<CurrencyModel.Empty();
private static readonly object LockObj = new object();
public static void RefreshLiveExchangeRates()
{
lock (LockObj)
{
CurrencyManager.currencies = GetSomeFooLiveDataFromInternet();
}
}
public static IEnumerable<CurrencyModel> GetCurrencies()
{
return CurrencyManager.currencies;
}
}
Renaming the method to something that better describes what is actually happening. When you call it GetLiveExchangeRates, I would expect it to return back the exchange rates rather than void. I'd then delete the constructor all together and create a GetCurrencies() method that returns the collection, or an empty one if the collection is null. It seems like the collection you are exposing, Currencies, should not be exposed publicly as a List as that allows consumers to change it. You haven't explained what the point of the collection is, so I'm making an assumption by trying to infer what is happening through your naming conventions.
If I were to write this, I would probably hide this behind a service instead. Removing the need for the static class. You hold a reference to the exchange rates in your view model/controller/service what-have-you. When you need to refresh them, hit the service again.
Service
public class CurrencyService
{
public IEnumerable<CurrencyModel> GetLiveExchangeRates()
{
return GetSomeFooLiveDataFromInternet();
}
}
Consumer (viewmodel/controller etc)
public class MyController
{
private IEnumerable<CurrencyModel> currentRates;
public MyController()
{
// Instance a new service; or provide it through the constructor as a dependency
var currencyService = new CurrencyService();
this.currentRates = currencyService.GetLiveExchangeRates();
}
}
Then your consuming class would use the collection it fetched from the service. If it wants to, it can pass around that collection to other objects that depend on it. When you feel the collection is stale, you re-fetch them from the service. At this point, you probably wouldn't need to do any locking because only the consumer can use the property and can control when it can and will change the property. This lets multiple instances query for the latest exchange rates without having to do a lock and make everyone queue up to receive them.
Ideally, I'd like to see it passed in as a dependency via the constructor, hidden behind an interface, with the rates refreshed at the time they are needed. So instead of fetching the rates in the constructor, I would fetch them lazily when needed. This would let you do the work async (assuming your real implementation is async).
Edit
If you are storing the collection in the static class for caching purposes, you could store the collection in the service, and always return the collection. The only time a new set of exchange rates is returned is when you clear the cache.
public class CurrencyService
{
private static IEnumerable<CurrencyModel> currencyRates;
private static object ratesLock = new object();
public IEnumerable<CurrencyModel> GetLiveExchangeRates()
{
if (currencyRates == null)
{
lock (ratesLock)
{
currencyRates = GetSomeFooLiveDataFromInternet();
}
}
return currencyRates;
}
public void ClearRates()
{
currencyRates = null;
}
}
This is more or less an implementation change. Your controller/viewmodel would continue to hit GetLiveExchangeRates(), but it would only fetch them once from your external service. Each time afterwards it would just return the cache. You only pay the locking fee once, then when other objects hit your service concurrently you don't pay the locking fee again.

Related

Storing/Saving a Method and later re-calling it

What I am currently atempting to make is an inventory system. I wonder if I can store the current method and then open the inventory, and when I am done there, reopen/recall the previus method that ran.
You haven't provided very much information but I can tell you don't want to store a method, you want to store an object.
An object is an instance of a class. Depending on the kind of class you have you can either create multiple instances of a class and instantiate them multiple times across your application. Or alternatively you can create single instances of an object that you use throughout your entire application/game.
From the sounds of it, you want to use a singleton class that retains the current values of the user's inventory. So if you interact with the inventory class in one part of your program, you would like to then view and interact with the same previously modified values stored within the singleton from another part of your program.
I can't give you a concrete answer to your problem, but a possible Singleton class for your use case would look something like this;
public sealed class Inventory
{
private static readonly Inventoryinstance = new Inventory();
// Explicit static constructor to tell C# compiler
// not to mark type as before field init
static Inventory()
{
}
private Inventory()
{
// optionally, pre-populate with data stored in database when constructed
}
public static Inventory Instance
{
get
{
return instance;
}
}
public List<InventoryItem> InventoryItems { get; set; } = new List<InventoryItem>();
public void AddItemToInventory(InventoryItem item) {
InventoryItems.Add(item);
}
public void RemoveItemFromInventory(InventoryItem item) {
InventoryItems.Remove(item);
}
}
You can use this site for reference - https://csharpindepth.com/articles/singleton
If you have an application that utilises DI, you can create singleton instances that are injectable into your other app classes. This is a better way of handling singletons as they are handled by an IoC system rather than being made static for the entire application to access.

Using IObservable<T> to keep track of current state

Suppose I have an object that observes an IObservable so that it's always aware of the current state of some external source. Internally my object has a method that uses that external value as part of the operation:
public class MyObject
{
public MyObject(IObservable<T> externalSource) { ... }
public void DoSomething()
{
DoSomethingWith(CurrentT);
}
}
What's the idomatic 'reactive' way of using IObservable for 'tracking current state' instead of 'responding to stream of events'.
Idea #1 is to just monitor the observable and write down values as they come in.
public class MyObject
{
private T CurrentT;
public MyObject(IObservable<T> externalSource)
{
externalSource.Subscribe((t) => { CurrentT = t; });
}
public void DoSomething()
{
DoSomethingWith(CurrentT);
}
}
And that's fine, but keeping track of the state in a class member seems very un-reactive-y.
Idea #2 is to use a BehaviorSubject
public class MyObject
{
private readonly BehaviorSubject<T> bs;
public MyObject(BehvaiorSubject<T> externalSource)
{
this.bs = externalSource
}
public void DoSomething()
{
DoSomethingWith(bs.Value);
}
}
But using subjects directly seems to be frowned upon. But at least in this case I have the ability to use a readonly field to store the behaviorsubject.
The BehaviorSubject (or ReplaySubject) does seem like it was made for this purpose, but is there some other better way here? And if I should use the subject, would it make more sense to take the subject as an injected parameter, or take the original observable and build the subject locally in the constructor?
(by the way I'm aware about the need to deal with the 1st value if the source observable hasn't fired yet. Don't get hung up on that, that's not what I'm asking about)
I'd go with a generic solution utilizing the ReactiveUI library. RUI has a standard way of mapping IObservable<T> to an INotifyPropertyChanged stateful property.
public class ObservableToINPCObject<T> : ReactiveObject, IDisposable
{
ObservableAsPropertyHelper<T> _ValueHelper;
public T Value {
get { return _ValueHelper.Value; }
}
public ObservableToINPCObject(IObservable<T> source, T initial = default(T))
{
_ValueHelper = source.ToProperty(this, p=>p.Value, initial);
}
public Dispose(){
_ValueHelper.Dispose();
}
}
ValueHelper is contains both the current state of the observable and automatically triggers the correct INPC notification when the state changes. That's quite a bit of boiler plate handled for you.
and an extension method
public static class ObservableToINPCObject {
public static ObservableToINPCObject<T> ToINPC<T>
( this IObservable<T> source, T init = default(T) )
{
return new ObservableToINPCObject(source, init);
}
}
now given an
IObservable<int> observable;
you can do
var obj = observable.ToINPC(10);
and to get the latest value
Console.WriteLine(obj.Value);
also given that Value is an INPC supporting property you can use it in databinding. I use ToProperty all the time for exposing my observables as properties for WPF databinding.
To be Rx-ish I'd suggest avoiding the second option and go with your first, but modified in one of two ways.
Either (1) make your class disposable so that you can cleanly close off the subscription to the observables or (2) make a method that lets you clean up individual observables.
(1)
public class MyObject : IDisposable
{
private T CurrentT;
private IDisposable Subscription;
public MyObject(IObservable<T> externalSource)
{
Subscription = externalSource
.Subscribe((t) => { CurrentT = t; });
}
public void Dispose()
{
Subscription.Dispose();
}
public void DoSomething()
{
DoSomethingWith(CurrentT);
}
}
(2)
public class MyObject
{
private T CurrentT;
public IDisposable Observe(IObservable<T> externalSource)
{
return externalSource
.Subscribe((t) => { CurrentT = t; });
}
public void DoSomething()
{
DoSomethingWith(CurrentT);
}
}
Both allow proper clean-up and both don't use a subject.

Lock code section in c#

My question may sound like many others here but it has a flavor I didn't find.
I am trying to understand the following logic
A generic object
public class GenericClass
{
public static void DoSomething(Object lockObj)
{
lock(lockObj)
{
// do something here
}
}
}
Class A
internal class A
{
private static _aLock = new Object();
public void Do_A_Thing()
{
GenericClass.DoSomething(_aLock);
}
}
Class B
internal class B
{
private static _bLock = new Object();
public void Do_B_Thing()
{
GenericClass.DoSomething(_bLock);
}
}
I just hope to confirm if my explanation is correct:
If multiple threads of class "A" will attempt simultaneously access code in "genericClass" method "DoSomething", this method will be locked to all but one instance of class "A". But a single instance of class "B" will be able to proceed with execution any time. If class "B" will also have multiple instances execute, they will not interfere with class "A" locks.
Is this correct based on what you see above?
Yes, your description sounds correct. It is perhaps a little unusual to pass the lock object in, but it'll work fine. The only change I would suggest is to make the static fields readonly so you can't accidentally change the value to a different object reference.
Your conclusion is correct but it is not a good practice to pass locked object around. I suggest to put the lock inside class A and B respectively.
I suggest to write:
internal class A
{
private static readonly _aLock = new Object();
public void Do_A_Thing()
{
lock (_aLock)
{
GenericClass.DoSomething();
}
}
}
Do you have a specific reason to put the lock in another class? Maybe you can solve your problem in a different way?
Also keep in mind that in some conditions, maybe it is not your case, you can have a deadlock if class A and B call each other (A->B->A).
Yes, that is correct. The locks in A and the locks in B are completely unaware of each other. The code will only be blocked when there is another thread locking it with the same object as identifier.
If you are using generics, then something like
public class MyGadget<T>
{
static readonly SyncRoot = new object() ;
public T SynchronizedMethod()
{
lock ( SyncRoot )
{
SynchronizedMethodGuts() ;
}
}
}
should do what you want because MyGadget<Foo> and MyGadget<Bar> are different classes: they each have their own, different SyncRoot field.

Refactoring a static class to use with dependency injection

We need to use an unmanaged library in our code that has static methods. I'd like to introduce the library operation as a dependency in my code. And apart from having static methods, the library has an initialization method and a settings method, both are global. So I can't just wrap this in an instance class, because if one instance changes a setting, all other instances will be affected, and if one instance gets initialized, all other instances will be reinitialized.
I thought about introducing it as a singleton class. This way it will be in an instance class, but there will only be one instance thus I won't have to worry about changing the settings or initialization. What do you think about this approach? I'm pretty new to the dependency injection pattern and I'm not sure if the singleton pattern is a good solution? What would your solution be to a similar case?
Edit: The initialization takes a parameter too, so I can't just lock the method calls and re-initialize and change settings every time it is called.
Edit 2: Here are the signatures of some methods:
public static void Initialize(int someParameter)
// Parameter can only be changed by re-initalization which
// will reset all the settings back to their default values.
public static float[] Method1(int someNumber, float[] someArray)
public static void ChangeSetting(string settingName, int settingValue)
If you only need to set the settings once at start up, then I would recommend making a non-static wrapper class which does all the initialization of the static class in its own static constructor. That way you can be assured that it will only happen once:
public class MyWrapper
{
public MyWrapper()
{
// Do any necessary instance initialization here
}
static MyWrapper()
{
UnManagedStaticClass.Initialize();
UnManagedStaticClass.Settings = ...;
}
public void Method1()
{
UnManagedStaticClass.Method1();
}
}
However, if you need to change the settings each time you call it, and you want to make your instances thread-safe, then I would recommend locking on a static object so that you don't accidentally overwrite the static settings while they're still in use by another thread:
public class MyWrapper
{
public MyWrapper()
{
// Do any necessary instance initialization here
}
static MyWrapper()
{
UnManagedStaticClass.Initialize();
}
static object lockRoot = new Object();
public void Method1()
{
lock (lockRoot)
{
UnManagedStaticClass.Settings = ...;
UnManagedStaticClass.Method1();
}
}
}
If you need to pass initialization parameters into your class's instance constructor, then you could do that too by having a static flag field:
public class MyWrapper
{
public MyWrapper(InitParameters p)
{
lock (lockRoot)
{
if (!initialized)
{
UnManagedStaticClass.Initialize(p);
initialized = true;
}
}
}
static bool initialized = false;
static object lockRoot = new Object();
public void Method1()
{
lock (lockRoot)
{
UnManagedStaticClass.Settings = ...;
UnManagedStaticClass.Method1();
}
}
}
If you also need to re-initialize each time, but you are concerned about performance because re-initializing is too slow, then the only other option (outside of the dreaded singleton) is to auto-detect if you need to re-initialize and only do it when necessary. At least then, the only time it will happen is when two threads are using two different instances at the same time. You could do it like this:
public class MyWrapper
{
public MyWrapper(InitParameters initParameters, Settings settings)
{
this.initParameters = initParameters;
this.settings = settings;
}
private InitParameters initParameters;
private Settings settings;
static MyWrapper currentOwnerInstance;
static object lockRoot = new Object();
private void InitializeIfNecessary()
{
if (currentOwnerInstance != this)
{
currentOwnerInstance = this;
UnManagedStaticClass.Initialize(initParameters);
UnManagedStaticClass.Settings = settings;
}
}
public void Method1()
{
lock (lockRoot)
{
InitializeIfNecessary();
UnManagedStaticClass.Method1();
}
}
}
I would use a stateless service class, and pass in state info for the static class with each method call. Without knowing any details of you class, I'll just show another example of this with a c# static class.
public static class LegacyCode
{
public static void Initialize(int p1, string p2)
{
//some static state
}
public static void ChangeSettings(bool p3, double p4)
{
//some static state
}
public static void DoSomething(string someOtherParam)
{
//execute based on some static state
}
}
public class LegacyCodeFacadeService
{
public void PerformLegacyCodeActivity(LegacyCodeState state, LegacyCodeParams legacyParams)
{
lock (_lockObject)
{
LegacyCode.Initialize(state.P1, state.P2);
LegacyCode.ChangeSettings(state.P3, state.P4);
LegacyCode.DoSomething(legacyParams.SomeOtherParam);
//do something to reset state, perhaps
}
}
}
You'll have to fill in the blanks a little bit, but hopefully you get the idea. The point is to set state on the static object for the minimum amount of time needed, and lock access to it that entire time, so no other callers can be affected by your global state change. You must create new instances of this class to use it, so it is fully injectable and testable (except the step of extracting an interface, which I skipped for brevity).
There are a lot of options in implementation here. For example, if you have to change LegacyCodeState a lot, but only to a small number of specific states, you could have overloads that do the work of managing those states.
EDIT
This is preferable to a singleton in a lot of ways, most importantly that you won't be able to accumulate and couple to global state: this turns global state in to non-global state if it is the only entry point to your static class. However, in case you do end up needing a singleton, you can make it easy to switch by encapsulating the constructor here.
public class LegacyCodeFacadeService
{
private LegacyCodeFacadeService() { }
public static LegacyCodeFacadeService GetInstance()
{
//now we can change lifestyle management strategies later, if needed
return new LegacyCodeFacadeService();
}
public void PerformLegacyCodeActivity(LegacyCodeState state, LegacyCodeParams legacyParams)
{
lock (_lockObject)
{
LegacyCode.Initialize(state.P1, state.P2);
LegacyCode.ChangeSettings(state.P3, state.P4);
LegacyCode.DoSomething(legacyParams.SomeOtherParam);
//do something to reset state, perhaps
}
}
}

Encapsulating an expensive resource without using a Singleton

I am working on updating a legacy application that is absolutely rife with Singleton classes. A perfect example would be the SnmpConnector class:
public SnmpConnector
{
public static IEnumerable<string> HostIpAddresses
{
...
}
private static SnmpConnector instance;
public static SnmpConnector Instance
{
if (instance == null)
instance = new SnmpConnector();
return instance;
}
private SnmpConnector()
{
foreach (string IpAddress in HostIpAddresses)
{
...
}
}
...
}
The goal of this update is to increase testability of the codebase, and as such I want to get rid of the Singletons. I've already abstracted away the data source of the SnmpConnector to either get data from a test database or from querying a live server:
public interface ISnmpDataSource
{
public DataTable MacTable
{
get;
private set;
}
public DataTable PortTable
{
get;
private set;
}
...
}
public TestSnmpDataSource : ISnmpDataSource
{
public FileInfo DataSource
{
get;
private set;
}
...
}
public SnmpDataSource : ISnmpDataSource
{
public List<string> HostIpAddresses
{
get;
private set;
}
...
}
public SnmpConnector
{
public SnmpConnector(ISnmpDataSource DataSource)
{
...
}
...
}
Now, I'm trying to test these components and running into the problem that probably caused SnmpConnector to be a Singleton in the first place: it takes an ungodly amount of time to test the SnmpDataSource. It turns out that fetching the MAC table and Port table from live switches takes somewhere between 10 and 20 seconds. I've already written 13 unit tests for this particular class, so it takes over two minutes for just these tests to complete. As annoying as this is, it gets worse once these updates get published to our original codebase. With this new refactoring, there is nothing stopping a programmer from creating and discarding an SnmpDataSource repeatedly.
Now, the data from these tables is largely static; the old Singleton and the new SnmpDataSource both maintain a cache that was only updated every four hours. Will I have to make SnmpDataSource a Singleton to prevent this problem?
Use dependency injection, and either pass the SnmpDataSource into anything that needs it, or potentially pass in a Func<SnmpDataSource> which can create the instance lazily as necessary.
Is your goal that the SnmpDataSource should update itself, or that callers will get a new version after a few hours?
You could try wrapping/decorating the SnmpDataSource with a cache-aware version that implements the same interface, then inject the cache-aware version.
*edit -- or you could do what Jon suggested where the factory Func does the caching instead (it will return a new instance or a cached version depending on when the last one was created). Same thing, slightly different implementation. Jon's version probably makes more sense.
public CachedSnmpDataSource : ISnmpDataSource
{
private DateTime m_lastRetrieved;
private TimeSpan m_cacheExpiryPeriod;
private List<string> m_hostIpAddresses;
private Func<SnmpDataSource> m_dataSourceCreator
public CachedSnmpDataSource(Func<SnmpDataSource> dataSourceCreator, TimeSpan cacheExpiryPeriod)
{
m_dataSourceCreator = dataSourceCreator;
m_cacheExpiryPeriod = cacheExpiryPeriod;
}
public List<string> HostIpAddresses
{
get
{
if(!IsRecentCachedVersionAvailable())
{
CreateCachedVersion();
}
return new List<string>(m_hostIpAddresses);
}
private bool IsRecentCachedVersionAvailable()
{
return m_hostIpAddresses != null &&
(DateTime.Now - m_lastRetrieved) < m_cacheExpiryPeriod;
}
private void CreateCachedVersion()
{
SnmpDataSource dataSource = m_dataSourceCreator();
m_hostIpAddresses = dataSource.HostIpAddresses;
m_lastRetrieved = DateTime.Now;
}
}
...
}
After a couple of iterations, I've ended up with a neat solution to this problem. I'm going to leave the accepted answer as is, but this is what I ultimately used:
ISnmpDataSource is responsible for fetching data, as before.
The SnmpConnector knows to only query if its own cache is invalid.
A static Factory class maintains a Dictionary<ISnmpDataSource, SnmpConnector>. There is a static BuildSnmpConnector(ISnmpDataSource) method based on this dictionary.
Using the library now looks like this:
IEnumerable<string> IpAddresses = ...;
string SqlConString = #"...";
ISnmpDataSource Switches = new SnmpDataSource(IpAddresses, SqlConStr);
SnmpConnector instance = Factory. BuildSnmpConnector(Switches);
I had a few problems with how I implemented GetHashCode and Equals for the ISnmpDataSource implementations, but formalizing a definition of equality pretty much fixed all those problems.
I'm pretty happy with the final result; the Factory class is responsible for limiting instantiation, while the SnmpConnector is responsible for caching query results, while the ISnmpDataSource is responsible for actually running queries. I'm sure there is a better organization out there, but this one is clean enough for use.

Categories