I have a static class that gets me a client..
public static ClientFactory {
private static Lazy<IClient> _MyClient;
public static IClient GetClient(ICache cache) {
if (_MyClient == null) {
_MyClient = new Lazy<IClient>(() => CreateClient(cache));
}
return _MyClient.Value;
}
private static IClient CreateClient(ICache cache) {
// code that takes 1-2 seconds to complete
return new Client(cache);
}
}
Is there any chance that I can have 2 or more clients created by writing code like this? Where the second client would overwrite the first one?
How should I update my code in a way, such that the constructor is called only once per application?
Thanks.
Yes, your code can result in multiple Client objects created. Use a static constructor to create the Lazy<IClient> instance:
public static ClientFactory
{
...
static ClientFactory()
{
_myClient = new Lazy<IClient>(() => CreateClient());
}
public IClient GetClient() => _myClient.Value;
}
Example execution from your code:
thread A evaluates _myClient == null as true, enters block
thread B evaluates _myClient == null as true, enters block
thread A creates Lazy<IClient> object and sets _myClient field
thread A exits if block
before thread B sets _myClient field with a new Lazy<IClient> object, thread A accesses _myCilent.Value property, resulting in the creation of your Client object
thread B sets the _myClient field to its new Lazy<IClient> object
thread B accesses the _myClient.Value property, creating a second Client object
all subsequent calls to GetClient will return this second instance of Client
Yes, there is a chance, consider this example, based on your input, a run of this simple program may result in initialization of one or two clients (run multiple times to see):
void Main()
{
System.Threading.Tasks.Parallel.Invoke(
() => ClientFactory.GetClient(1),
() => ClientFactory.GetClient(2));
}
// You can define other methods, fields, classes and namespaces here
public static class ClientFactory {
private static Lazy<IClient> _MyClient;
public static IClient GetClient(int init) {
Console.WriteLine(_MyClient == null);
if (_MyClient == null) {
Console.WriteLine(init);
_MyClient = new Lazy<IClient>(() => CreateClient());
}
return _MyClient.Value;
}
private static IClient CreateClient() {
// code that takes 1-2 seconds to complete
return new Client();
}
}
public interface IClient {
}
public class Client : IClient {
public Client() {
Console.WriteLine("Client constucrtor");
}
}
Two threads may be within the if (_MyClient == null) clause in the same time, creating multiple objects, only one assigned.
Related
This is a simplified version of production code and running in multi thread with singleton. Compared to traditional singleton the additional thing is that I initialized client in the lock section.
When I trying to get the client by: Client client = Singleton.Instance.GetClient();, there is chance that client can be null (but the chance is very small).
public class Client
{
public int Value { get; set; } = 10;
}
public class Singleton
{
private static Singleton instance = null;
private static readonly object padlock = new object();
private Client client = null;
public static Singleton Instance
{
get
{
if (instance == null)
{
lock (padlock)
{
if (instance == null)
{
instance = new Singleton();
// Here is the interesting part!
instance.InitClient();
}
}
}
return instance;
}
}
private void InitClient()
{
this.client = new Client();
}
public Client GetClient()
{
return this.client;
}
}
This is how I testing it:
static void Main(string[] args)
{
Console.WriteLine("Input thread count: ");
int threadCount = Int32.Parse(Console.ReadLine().Trim());
List<Task> tasks = new List<Task>(threadCount);
for (int i = 0; i < threadCount; ++i)
{
tasks.Add(Task.Factory.StartNew(() => DoStuff()));
}
Task.WaitAll(tasks.ToArray());
Console.WriteLine("All threads complete");
}
private static void DoStuff()
{
Client client = Singleton.Instance.GetClient();
if (client.Value != 10)
{
Console.WriteLine($"Thread: {Thread.CurrentThread.ManagedThreadId}.");
}
}
And client can be null in occasionlly:
But when I moved the InitClient() into the private constructor of Singleton, I never meet the situation that client is null:
private Singleton()
{
this.InitClient();
}
I don't have any clue what is difference and what is wrong, thanks for the helping!
As soon as you call instance = new Singleton() inside the lock, "instance" is no longer null, meaning separate (threaded) calls to Singleton.Instance returns immediately, and a call to GetClient on that instance would be a race condition with the InitClient from the first call.
Initializing inside the constructor ensures "Instance" itself is initialized as soon as it's created. So subsequent calls from separate threads wouldn't race against anything.
I'm using the following service method in order to cache the result of a query:
private readonly CoreDbContext _dbContext;
public EcommerceProductService()
{
_dbContext = GetDbContext();
}
public IEnumerable<EcommerceProduct> GetAllCached()
{
var cachedResult = HttpContext.Current.Cache["EcommerceProductService.GetAllCached"] as IEnumerable<EcommerceProduct>;
if (cachedResult == null)
{
var result = _dbContext.EcommerceProducts.ToList();
HttpContext.Current.Cache.Insert("EcommerceProductService.GetAllCached", result);
return result;
}
return cachedResult;
}
In a certain page, this method is called simultaneously by 2 threads (because I need to display the entire collection of products twice, but with different filters).
Oddly, the first time I launch the application only one of the threads "wins" and receives the list of products, while the other receives null. If I refresh the page they both start to work fine (because at that point they fetch the result from the cache), but the first time it's only one or the other, they never both work.
I also tried to wrap the entire code in a Lock statement, but it didn't change a thing. What am I missing?
private readonly CoreDbContext _dbContext;
private static readonly object Locker = new object();
public EcommerceProductService()
{
_dbContext = GetDbContext();
}
public IEnumerable<EcommerceProduct> GetAllCached()
{
lock (Locker)
{
var cachedResult = HttpContext.Current.Cache["EcommerceProductService.GetAllCached"] as IEnumerable<EcommerceProduct>;
if (cachedResult == null)
{
var result = _dbContext.EcommerceProducts.ToList();
HttpContext.Current.Cache.Insert("EcommerceProductService.GetAllCached", result);
return result;
}
return cachedResult;
}
}
Change your _locker declaration to
private static object _locker = new object();
As you have it now, each instance of EcommerceProductService assigns a new value to it, rendering locking useless.
I have been playing around with ways to implement Singletons. I have written a little management object that allows for a easier, less code approach to writing singleton classes.
I would never use something like this in a production system for a couple of reason which lead me to my question.
With the below code - I am assuming that this implementation would/could lead to both threading issues and memory leaks? Would I be correct?
namespace ConsoleApplication1
{
public static class SingletonManager
{
private static readonly Dictionary<string, object> Objects;
static SingletonManager()
{
Objects = new Dictionary<string, object>();
}
public static T InstanceOf<T>(object[] ctorArgs = null)
where T : class
{
var name = typeof (T).FullName;
if (Objects.ContainsKey(name))
return Objects[name] as T;
var ctor = typeof (T).GetConstructors(
BindingFlags.Instance |
BindingFlags.NonPublic)[0];
var instance = ctor.Invoke(ctorArgs) as T;
Objects[name] = instance;
return instance as T;
}
public static void DisposeOf<T>()
where T : Singleton<T>
{
Dispose(typeof (T).FullName);
}
public static void DisposeOf(Type type)
{
Dispose(type.FullName);
}
private static void Dispose(string name)
{
if (!Objects.ContainsKey(name)) return;
var obj = Objects[name];
if (obj is IDisposable)
((IDisposable) Objects[name]).Dispose();
Objects.Remove(name);
}
}
public class Singleton<T>
where T : class
{
private static object ThreadLock = new object();
public static T Instance(object[] ctorArgs = null)
{
lock (ThreadLock)
{
return SingletonManager.InstanceOf<T>(ctorArgs);
}
}
}
public class SomeSingletonClass : Singleton<SomeSingletonClass>
{
public int Number;
private SomeSingletonClass(int i)
{
Number = i;
}
}
internal class Program
{
private static void Main(string[] args)
{
var instance1= SomeSingletonClass.Instance(new object[] {1});
var instance2 = SomeSingletonClass.Instance(new object[] { 2 });
//Is false
var updated = instance1.Number == 2;
instance2.Number = 99;
//Is true
var equals = instance1.Number == instance2.Number;
//Is true
var refEquals = ReferenceEquals(instance1, instance2);
Debugger.Break();
}
}
}
Classical singletons are very rarely a good idea. In most cases you're better off with simply creating a single instance which you pass to the code that needs it, instead of enforcing that there is only one. An IoC container will do most of that work for you.
An implementation of a classical singleton is quite compact, no need to simplify it further:
public class MySingleton
{
private static Lazy<MySingleton> _instance = new Lazy<MySingleton>(() => new MySingleton());
public static MySingleton Instance { get { return _instance.Value; } }
private MySingleton()
{
}
}
At best you can save two of these lines.
Yes, your code is not thread safe. You'd need to put most of it in lock statements to fix that.
The consumer determining the constructor parameters is very dubious. Unless all of them are identical, you'll end up with different instances, depending on which consumer runs first.
This violates the "single source of truth" principle and is a maintenance and debugging nightmare.
Your code relies on private reflection.
I am writing extension methods for a class, and would like to access an IDisposable object defined in a using block which will often contain calls to the extension methods.
I do not want to simply pass the IDisposable to the method calls, which would detract from the simplicity of my API's programming model. Accomplishing what I'm after would also make the code work much more like the third-party API with which I'm integrating.
I can imagine one way to go about this: register the IDisposable in some global location, perhaps tied to the current thread ID so it can be looked up in the extension methods via a factory method call or some such thing. The object could unregister itself when the using block is exited and its Dispose() method is eventually called (to make this work I imagine I might need to use a weak reference, though).
That doesn't seem very unclean, but it is a little too much roundabout for my taste. Is there some more direct way of doing this?
Here's what I'd like to do:
public static class ExtensionMethods {
public static void Foo(this Bar b) {
// Access t to enable this extension method to do its work, whatever that may be
}
}
public class Bar {
}
public class Schlemazel {
public void DoSomething() {
using (Thingamabob t = new Thingamabob()) {
Bar b = new Bar();
b.Foo();
}
}
}
EDIT:
Following is a solution implemented using weak references and a simple thread-based registration system. It seems to work and to be stable even under a fair load, but of course on a really overloaded system it could theoretically start throwing errors due to lock contention.
I thought it might be interesting for someone to see this solution, but again, it introduces needless complexity and I am only willing to do this if necessary. Again, the goal is a clean extension of a third-party API, where I can call extension methods on objects created by the third-party API, where the extension methods depend on some context that is messy to create or get for each little extension method call.
I've left in some console output statements so that if you're curious, you can actually plop these classes into a command-line project and see it all in action.
public class Context : IDisposable
{
private const int MAX_LOCK_TRIES = 3;
private static TimeSpan MAX_WRITE_LOCK_TIMEOUT = TimeSpan.FromTicks(500);
private static System.Threading.ReaderWriterLockSlim readerWriterLock = new System.Threading.ReaderWriterLockSlim();
static IDictionary<string, WeakReference<Context>> threadContexts = new Dictionary<string, WeakReference<Context>>();
private bool registered;
private string threadID;
private string ThreadID
{
get { return threadID; }
set
{
if (threadID != null)
throw new InvalidOperationException("Cannot associate this context with more than one thread");
threadID = value;
}
}
/// <summary>
/// Constructs a Context suitable for use in a using() statement
/// </summary>
/// <returns>A Context which will automatically deregister itself when it goes out of scope, i.e. at the end of a using block</returns>
public static Context CreateContext()
{
Console.WriteLine("CreateContext()");
return new Context(true);
}
private Context(bool register)
{
if (register)
{
registered = true;
try
{
RegisterContext(this);
}
catch
{
registered = false;
}
}
else
registered = false;
}
public Context()
{
registered = false;
}
public void Process(ThirdPartyObject o, params string[] arguments)
{
Console.WriteLine("Context.Process(o)");
// Process o, sometimes using the third-party API which this object has access to
// This hides away the complexity of accessing that API, including obviating the need
// to reconstruct and configure heavyweight objects to access it; calling code can
// blithely call useful methods on individual objects without knowing the messy details
}
public void Dispose()
{
if (registered)
DeregisterContext(this);
}
private static void RegisterContext(Context c)
{
if (c == null)
throw new ArgumentNullException();
c.ThreadID = System.Threading.Thread.CurrentThread.ManagedThreadId.ToString();
Console.WriteLine("RegisterContext() " + c.ThreadID);
bool lockEntered = false;
int tryCount = 0;
try
{
while (!readerWriterLock.TryEnterWriteLock(TimeSpan.FromTicks(5000)))
if (++tryCount > MAX_LOCK_TRIES)
throw new OperationCanceledException("Cannot register context (timeout)");
lockEntered = true;
threadContexts[c.ThreadID] = new WeakReference<Context>(c);
}
finally
{
if (lockEntered)
readerWriterLock.ExitWriteLock();
}
}
private static void DeregisterContext(Context c)
{
if (c == null)
throw new ArgumentNullException();
else if (!c.registered)
return;
Console.WriteLine("DeregisterContext() " + c.ThreadID);
bool lockEntered = false;
int tryCount = 0;
try
{
while (!readerWriterLock.TryEnterWriteLock(TimeSpan.FromTicks(5000)))
if (++tryCount > MAX_LOCK_TRIES)
throw new OperationCanceledException("Cannot deregister context (timeout)");
lockEntered = true;
if (threadContexts.ContainsKey(c.ThreadID))
{
Context registeredContext = null;
if (threadContexts[c.ThreadID].TryGetTarget(out registeredContext))
{
if (registeredContext == c)
{
threadContexts.Remove(c.ThreadID);
}
}
else
threadContexts.Remove(c.ThreadID);
}
}
finally
{
if (lockEntered)
readerWriterLock.ExitWriteLock();
}
}
/// <summary>
/// Gets the Context for this thread, if one has been registered
/// </summary>
/// <returns>The Context for this thread, which would generally be defined in a using block using Context.CreateContext()</returns>
internal static Context GetThreadContext()
{
string threadID = System.Threading.Thread.CurrentThread.ManagedThreadId.ToString();
Console.WriteLine("GetThreadContext() " + threadID);
bool lockEntered = false;
int tryCount = 0;
try
{
while (!readerWriterLock.TryEnterReadLock(TimeSpan.FromTicks(5000)))
if (++tryCount > MAX_LOCK_TRIES)
throw new OperationCanceledException("Cannot get context (timeout)");
lockEntered = true;
Context registeredContext = null;
if (threadContexts.ContainsKey(threadID))
threadContexts[threadID].TryGetTarget(out registeredContext);
return registeredContext;
}
finally
{
if (lockEntered)
readerWriterLock.ExitReadLock();
}
}
}
// Imagine this is some third-party API
public static class ThirdPartyApi
{
// Imagine this is any call to the third-party API that returns an object from that API which we'd like to decorate with an extension method
public static ThirdPartyObject GetThirdPartyObject()
{
return new ThirdPartyObject();
}
}
// Imagine this is some class from a third-party API, to which we would like to add extension methods
public class ThirdPartyObject
{
internal ThirdPartyObject() { }
}
public static class ExtensionMethods
{
public static void DoSomething(this ThirdPartyObject o) {
// get the object I need to access resources to do my work
Console.WriteLine("o.DoSomething()");
Context c = Context.GetThreadContext();
c.Process(o);
}
}
You could test it pretty simply, with some code like this:
ThirdPartyObject o;
using (Context.CreateContext())
{
o = ThirdPartyApi.GetThirdPartyObject(); // or a call to my own code to get it, encapsulating calls to the third-party API
// Call the method we've tacked on to the third party API item
o.DoSomething();
}
try
{
// If the registered context has been disposed/deregistered, this will throw an error;
// there is of course no way of knowing when it will happen, but in my simple testing
// even this first attempt always throws an error, on my relatively unburdened system.
// This means that with this model, one should not access the using-block Context
// outside of the using block, but that's of course true in general of using statements
o.DoSomething();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
System.Threading.Thread.Sleep(1000);
try
{
// Should almost certainly see an error now
o.DoSomething();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
Pass the t variable to the extension method.
public static class ExtensionMethods {
public static void Foo(this Bar b, Thingamabob t) {
// Access t to enable this extension method to do its work, whatever that may be
}
}
public class Bar { }
public class Schlemazel {
public void DoSomething() {
using (Thingamabob t = new Thingamabob()) {
Bar b = new Bar();
b.Foo(t);
}
}
}
I need a way to lock c# threads by user
I have my data object and I create new instance for every user.
Every user has several threads that use this object and in I.O. operations I want to lock this object instance for this user only.
Using simple Lock {} is locking all the object instances, there for blocking other user.
I need some simple solution.
Edit
I build new instance of MyDataObj per user;
Then run job that updating some data in MyDataObj every minute;
Using lockObj as lock, lock the data to all the users (Although it's not static Variables)
I need only to lock the data to the current user
this is the code sample
public sealed class MyDataObj
{
private static readonly Dictionary<object, MyDataObj> _instances = new Dictionary<object, MyDataObj>();
public object lockObj = new object();
public bool jobRunning = false;
private string data = string.Empty;
//// --------- constractor -------------------
private MyDataObj(int key)
{
LoadMyDataObj(key);
}
public static MyDataObj GetInstance(int key)
{
lock (_instances)
{
MyDataObj instance;
if (_instances.TryGetValue(key, out instance))
{
instance = _instances[key];
return instance;
}
instance = new MyDataObj(key);
return instance;
}
}
private void LoadMyDataObj(int key)
{
// get the data from db
}
public void UpdateMyData(string newData)
{
lock (lockObj)
{
this.data = newData;
}
}
public string ReadMyData()
{
lock (lockObj)
{
return this.data;
}
}
public class ActionObject
{
MyDataObj myDataObj;
int UserID;
//// --------- constractor -------------------
public ActionObject(int userid)
{
this.UserID = userid;
myDataObj = MyDataObj.GetInstance(userid);
if (!myDataObj.jobRunning)
{
jobs jbs = new jobs(myDataObj);
System.Threading.Thread RunJob = new System.Threading.Thread(new System.Threading.ThreadStart(jbs.dominutesAssignment));
RunJob.Start();
myDataObj.jobRunning = true;
}
}
public ActionObject()
{
myDataObj = MyDataObj.GetInstance(this.UserID);
myDataObj.UpdateMyData("some data");
}
}
public class jobs
{
MyDataObj myDataObj = null;
public jobs(MyDataObj grp)
{
this.myDataObj = grp;
}
public void dominutesAssignment()
{
while (true)
{
myDataObj.ReadMyData();
System.Threading.Thread.Sleep(1000);
}
}
}
}
I need a way to lock c# threads by user. I have my data object and I create new instance for every user
Create one lock per user. Or if the user exists longer than the threads: Use the user object as the lock.
lock (userOrTheUserObject)
{
//Do some op
}
Every user has several threads that use this object and in I.O. operations
That sounds more like you should use asynchronous IO instead of creating several threads (which will be less effecient)
I want to lock this object instance for this user only. Using simple Lock {} is locking all the object instances, there for blocking other user.
If the object is shared between all users you HAVE to lock it using lock. The lock won't be very effective otherwise. The other object is to redesign the object to now be shared.
I need some simple solution.
There are no simple threading solutions.
You can use Monitor. In this sample anyone but user 1 can execute DoIt method concurrently. While user 1 executing DoIt no one can enter it. A weak point is if user 1 tries to execute DoIt when user 2 already executing it, user 2 continues its execution. Also you have to handle exceptions properly otherwise there may be dead locks.
private static readonly object lockObj = new Object();
public void Do(int userId)
{
Monitor.Enter(lockObj);
if (userId != 1)
Monitor.Exit(lockObj);
try
{
DoIt();
}
finally
{
if (userId == 1)
Monitor.Exit(lockObj);
}
}
public void DoIt()
{
// Do It
}