I have two generic methods in the same class, and each uses exactly the same code to create instances. One works, the other throws an AmbiguousMatchException. Here is the code:
private static Dictionary<Type, AccessBase> _dictionary;
public static T Access<T>(Type type) where T : AccessBase
{
T instantiated;
if (_dictionary.ContainsKey(type))
{
instantiated = _dictionary[type] as T;
}
else
{
instantiated = (T)Activator.CreateInstance(type, _manager); //<- Works!
_dictionary.Add(type, instantiated);
}
return instantiated;
}
public static void RegisterAccess<T>(Type type) where T : AccessBase
{
if (type == null)
{
throw new ArgumentNullException(nameof(type));
}
if (_dictionary.ContainsKey(type))
{
return;
}
var instantiated = (T)Activator.CreateInstance(type, _manager); //<- Fails!
if (instantiated == null)
{
throw new ArgumentException($"{nameof(type)} cannot be registered");
}
_dictionary.Add(type, instantiated);
}
I would welcome any suggestions as to why and what to do about it... I have been tearing what is left of my hair out over this one!
Thanks to all of you for your input. I finally found the problem, which as it turns out is quite simple actually. At the point of failure the value of the _manager field is null... As soon as it is no longer null, it works.
To trap this I tried calling the first method at the same time as the second, and both failed. Tracking it through, I determined that the cause was the null value, since if you do it later in the process it works fine.
The original purpose of the code was to pre-register the access classes so that when they are needed they are ready to go and avoid the constant 'new' calls to generate these classes as they are needed. Given that it is now clear that this cannot happen at that point, the question is whether this is required at all. If we do it at a later point, there is not much reason to do it as it will get repeated every time a database is opened with each one not being added as it already exists.
I think we will end up abandoning the process that uses the second method, the pre-registration, in favour of the first method which is already used anyway and which automatically adds the instantiated classes only when they are needed and which already works fine at the later point.
In the following example, _instance is always resolving to null. How should I be getting the value safely out of the thread?
class GenericThreadManager<TMyClass> where TMyClass : new()
{
private TMyClass _instance;
private object synLock = new object();
private Thread generalThread;
public GenericThreadManager()
{
//wrapped code
lock (this.synLock)
{
generalThread = new Thread(_instance => this._instance = new TMyClass());
generalThread.Start(); // instantiates the object
while (this._instance == null) // allways compares to null even after
// thread completes
{
Thread.Sleep(100);
}
Thread.Sleep(100);
}
//wrapped code
}
Edits based on comments (thank you for the comments)
The while loop after the thread is just to debug / test if the thread is ever completing.
The context – is that this class instantiates an object that takes a long time to build (i.e. loading lots of data) on a thread. This class then governs access to the object until the instantiation is complete. Crudely I was doing this by checking if the object was null.
Although there might be better ways to solve the problem – I would like to understand where I’ve gone wrong in my understanding of threaded code / and Lambda’s.
Crudely – I understood generalThread = new Thread(_instance => this._instance = new TMyClass()); to be setting the threadstart to the Lambda expression:
_instance => this._instance = new TMyClass()
I understand this expression creates a new instance of TMyClass() and place reference to that object in _instance.
I then understood that the threads my not be synchronised, so the value of _instance wouldn’t be reliably set – unless it was set to volatile.
With it set to volatile I get the following compile error:
Error CS0677 'GenericThreadManager<TMyClass>._instance': a volatile field cannot be of the type 'TMyClass'
How do I resolve the above error or synchronise the threads to move the reference to the object to _instance.
# Panagiotis Kanavos could you explain why the each constructor would see a different lock. The GenericThreadManager is making a private instance of TMyClass, a different object, in the GenericThreadManager constructor. It locking on synLock, so in theory, any other methods on GenericThreadManager should block on the lock (this.synLock) if I understand correctly?
I want to create a wrapper class for another type. This works fine until the point where it's necessary that (reference)-equal objects need to have (reference)-equal wrappers.
An example:
public interface ITest<T>
{
T GetInstance(bool createNew);
}
public class Test : ITest<Test>
{
private static Test instance;
public Test GetInstance(bool createNew)
{
if (instance == null || createNew)
{
instance = new Test();
}
return instance;
}
}
public class TestWrapper : ITest<TestWrapper>
{
private readonly Test wrapped;
public TestWrapper(Test wrapped)
{
this.wrapped = wrapped;
}
public TestWrapper GetInstance(bool createNew)
{
return new TestWrapper(wrapped.GetInstance(createNew));
}
}
Test.GetInstance returns always the same instance, as long as the parameter createNew is false.
By contrast TestWrapper.GetInstance returns always a new instance.
Since I want to be able to replace Test with TestWrapper, I search for a solution so that at the end, the wrapper returns a new instance only, if Test returns a new instance. However, the TestWrapper should have no knowledge about the internals of Test.
The test code is
private static void RunTest<T>(ITest<T> cls)
{
var i1 = (ITest<T>)cls.GetInstance(false);
var i2 = (ITest<T>)cls.GetInstance(false);
var i3 = (ITest<T>)cls.GetInstance(true);
var dic = new Dictionary<ITest<T>, bool>();
if (!dic.ContainsKey(i1)) dic.Add(i1, false); else dic[i1] = true;
if (!dic.ContainsKey(i2)) dic.Add(i2, false); else dic[i2] = true;
if (!dic.ContainsKey(i3)) dic.Add(i3, false); else dic[i3] = true;
Console.WriteLine(string.Join(", ", dic.Select(a => a.Value.ToString())));
}
The desired result is
True, False
and that's what you get if one passes new Test() to that method.
If you pass new TestWrapper(new Test()), you'll get
False, False, False
There is a solution based on a simple cache (Dictionary<Test, TestWrapper>) - but with that, I would hold many of the instances in memory without using them any further (and the GC could not collect those instances since there's a reference holding them).
I played around with WeakReferences a bit, but I can't spot a key that I can use to store the WeakReference - thus I have to iterate through the cache list and search for the correct instance which is slow. Besides, I've to implement this solution for every member (with it's very own cache) which seems not to be a great solution...
I hope I have adequately explained my problem ;) So, my questions are:
is there a way to cheat object.ReferenceEquals (that question is unrewarding)
what can I use (as a key for the cache) as an identifier for an object instance (so I can use WeakReference)
is there a better way to achieve a real adapter (where I can replace the adaptee with an adapter without headache)
I've no access to the Test class, and only limited access to the code that uses it (I'm able to pass an arbitrary instance as long it's implements the interface)
No, you can't cheat object.ReferenceEquals(). However, object.ReferenceEquals() is intentionally used very rarely, and usually in cases where things really do need to be reference-equal.
The runtime need it in order to get things right. E.g. if the instance is used as a key in an Dictionary<>
Actually, the runtime typically uses the .GetHashCode() and .Equals() behavior of the individual objects, but it just so happens that if you don't override that behavior in your classes, the base System.Object implementation of those methods relies on the object reference by default.
So if you have the ability to change the code for both the Test class and the TestWrapper class, you can override these equality methods in those classes to ensure that they recognize equivalent objects as equal.
An alternative (and usually better) approach would be to create an IEqualityComparer<> implementation to use in your specific use case. You mentioned keys in a Dictionary<>: you can provide an IEqualityComparer<> instance to the dictionary when it's created to have it test for equality in exactly the way you want.
var dict = new Dictionary<object, object(new TestsAndWrappersAreEqualComparer());
var test = Test.GetInstance(true);
var testWrapper = TestWrapper.GetInstance(true);
dict[test] = test;
Console.WriteLine(dict.ContainsKey(test)); // true
I'm attempting to write a thread-safe method which may only be called once (per object instance). An exception should be thrown if it has been called before.
I have come up with two solutions. Are they both correct? If not, what's wrong with them?
With lock:
public void Foo()
{
lock (fooLock)
{
if (fooCalled) throw new InvalidOperationException();
fooCalled = true;
}
…
}
private object fooLock = new object();
private bool fooCalled;
With Interlocked.CompareExchange:
public void Foo()
{
if (Interlocked.CompareExchange(ref fooCalled, 1, 0) == 1)
throw new InvalidOperationException();
…
}
private int fooCalled;
If I'm not mistaken, this solution has the advantage of being lock-free (which seems irrelevant in my case), and that it requires fewer private fields.
I am also open to justified opinions which solution should be preferred, and to further suggestions if there's a better way.
Your Interlocked.CompareExchange solution looks the best, and (as you said) is lock-free. It's also significantly less complicated than other solutions. Locks are quite heavyweight, whereas CompareExchange can be compiled down to a single CAS cpu instruction. I say go with that one.
The double checked lock patter is what you are after:
This is what you are after:
class Foo
{
private object someLock = new object();
private object someFlag = false;
void SomeMethod()
{
// to prevent locking on subsequent calls
if(someFlag)
throw new Exception();
// to make sure only one thread can change the contents of someFlag
lock(someLock)
{
if(someFlag)
throw new Exception();
someFlag = true;
}
//execute your code
}
}
In general when exposed to issues like these try and follow well know patters like the one above.
This makes it recognizable and less error prone since you are less likely to miss something when following a pattern, especially when it comes to threading.
In your case the first if does not make a lot of sense but often you will want to execute the actual logic and then set the flag. A second thread would be blocked while you are executing your (maybe quite costly) code.
About the second sample:
Yes it is correct, but don't make it more complicated than it is. You should have very good reasons to not use the simple locking and in this situation it makes the code more complicated (because Interlocked.CompareExchange() is less known) without achieving anything (as you pointed out being lock less against locking to set a boolean flag is not really a benefit in this case).
Task task = new Task((Action)(() => { Console.WriteLine("Called!"); }));
public void Foo()
{
task.Start();
}
public void Bar()
{
Foo();
Foo();//this line will throws different exceptions depends on
//whether task in progress or task has already been completed
}
I have a question about improving the efficiency of my program. I have a Dictionary<string, Thingey> defined to hold named Thingeys. This is a web application that will create multiple named Thingey’s over time. Thingey’s are somewhat expensive to create (not prohibitively so) but I’d like to avoid it whenever possible. My logic for getting the right Thingey for the request looks a lot like this:
private Dictionary<string, Thingey> Thingeys;
public Thingey GetThingey(Request request)
{
string thingeyName = request.ThingeyName;
if (!this.Thingeys.ContainsKey(thingeyName))
{
// create a new thingey on 1st reference
Thingey newThingey = new Thingey(request);
lock (this.Thingeys)
{
if (!this.Thingeys.ContainsKey(thingeyName))
{
this.Thingeys.Add(thingeyName, newThingey);
}
// else - oops someone else beat us to it
// newThingey will eventually get GCed
}
}
return this. Thingeys[thingeyName];
}
In this application, Thingeys live forever once created. We don’t know how to create them or which ones will be needed until the app starts and requests begin coming in. The question I have is in the above code is there are occasional instances where newThingey is created because we get multiple simultaneous requests for it before it’s been created. We end up creating 2 of them but only adding one to our collection.
Is there a better way to get Thingeys created and added that doesn’t involve check/create/lock/check/add with the rare extraneous thingey that we created but end up never using? (And this code works and has been running for some time. This is just the nagging bit that has always bothered me.)
I'm trying to avoid locking the dictionary for the duration of creating a Thingey.
This is the standard double check locking problem. The way it is implemented here is unsafe and can cause various problems - potentially up to the point of a crash in the first check if the internal state of the dictionary is screwed up bad enough.
It is unsafe because you are checking it without synchronization and if your luck is bad enough you can hit it while some other thread is in the middle of updating internal state of the dictionary
A simple solution is to place the first check under a lock as well. A problem with this is that this becomes a global lock and in web environment under heavy load it can become a serious bottleneck.
If we are talking about .NET environment, there are ways to work around this issue by piggybacking on the ASP.NET synchronization mechanism.
Here is how I did it in NDjango rendering engine: I keep one global dictionary and one dictionary per rendering thread. When a request comes I check the local dictionary first - this check does not have to be synchronized and if the thingy is there I just take it
If it is not I synchronize on the global dictionary check if it is there and if it is add it to my thread dictionary and release the lock. If it is not in the global dictionary I add it there first while still under lock.
Well, from my point of view simpler code is better, so I'd only use one lock:
private readonly object thingeysLock = new object();
private readonly Dictionary<string, Thingey> thingeys;
public Thingey GetThingey(Request request)
{
string key = request.ThingeyName;
lock (thingeysLock)
{
Thingey ret;
if (!thingeys.TryGetValue(key, out ret))
{
ret = new Thingey(request);
thingeys[key] = ret;
}
return ret;
}
}
Locks are really cheap when they're not contended. The downside is that this means that occasionally you will block everyone for the whole duration of the time you're creating a new Thingey. Clearly to avoid creating redundant thingeys you'd have to at least block while multiple threads create the Thingey for the same key. Reducing it so that they only block in that situation is somewhat harder.
I would suggest you use the above code but profile it to see whether it's fast enough. If you really need "only block when another thread is already creating the same thingey" then let us know and we'll see what we can do...
EDIT: You've commented on Adam's answer that you "don't want to lock while a new Thingey is being created" - you do realise that there's no getting away from that if there's contention for the same key, right? If thread 1 starts creating a Thingey, then thread 2 asks for the same key, your alternatives for thread 2 are either waiting or creating another instance.
EDIT: Okay, this is generally interesting, so here's a first pass at the "only block other threads asking for the same item".
private readonly object dictionaryLock = new object();
private readonly object creationLocksLock = new object();
private readonly Dictionary<string, Thingey> thingeys;
private readonly Dictionary<string, object> creationLocks;
public Thingey GetThingey(Request request)
{
string key = request.ThingeyName;
Thingey ret;
bool entryExists;
lock (dictionaryLock)
{
entryExists = thingeys.TryGetValue(key, out ret);
// Atomically mark the dictionary to say we're creating this item,
// and also set an entry for others to lock on
if (!entryExists)
{
thingeys[key] = null;
lock (creationLocksLock)
{
creationLocks[key] = new object();
}
}
}
// If we found something, great!
if (ret != null)
{
return ret;
}
// Otherwise, see if we're going to create it or whether we need to wait.
if (entryExists)
{
object creationLock;
lock (creationLocksLock)
{
creationLocks.TryGetValue(key, out creationLock);
}
// If creationLock is null, it means the creating thread has finished
// creating it and removed the creation lock, so we don't need to wait.
if (creationLock != null)
{
lock (creationLock)
{
Monitor.Wait(creationLock);
}
}
// We *know* it's in the dictionary now - so just return it.
lock (dictionaryLock)
{
return thingeys[key];
}
}
else // We said we'd create it
{
Thingey thingey = new Thingey(request);
// Put it in the dictionary
lock (dictionaryLock)
{
thingeys[key] = thingey;
}
// Tell anyone waiting that they can look now
lock (creationLocksLock)
{
Monitor.PulseAll(creationLocks[key]);
creationLocks.Remove(key);
}
return thingey;
}
}
Phew!
That's completely untested, and in particular it isn't in any way, shape or form robust in the face of exceptions in the creating thread... but I think it's the generally right idea :)
If you're looking to avoid blocking unrelated threads, then additional work is needed (and should only be necessary if you've profiled and found that performance is unacceptable with the simpler code). I would recommend using a lightweight wrapper class that asynchronously creates a Thingey and using that in your dictionary.
Dictionary<string, ThingeyWrapper> thingeys = new Dictionary<string, ThingeyWrapper>();
private class ThingeyWrapper
{
public Thingey Thing { get; private set; }
private object creationLock;
private Request request;
public ThingeyWrapper(Request request)
{
creationFlag = new object();
this.request = request;
}
public void WaitForCreation()
{
object flag = creationFlag;
if(flag != null)
{
lock(flag)
{
if(request != null) Thing = new Thingey(request);
creationFlag = null;
request = null;
}
}
}
}
public Thingey GetThingey(Request request)
{
string thingeyName = request.ThingeyName;
ThingeyWrapper output;
lock (this.Thingeys)
{
if(!this.Thingeys.TryGetValue(thingeyName, out output))
{
output = new ThingeyWrapper(request);
this.Thingeys.Add(thingeyName, output);
}
}
output.WaitForCreation();
return output.Thing;
}
While you are still locking on all calls, the creation process is much more lightweight.
Edit
This issue has stuck with me more than I expected it to, so I whipped together a somewhat more robust solution that follows this general pattern. You can find it here.
IMHO, if this piece of code is called from many thread simultaneous, it is recommended to check it twice.
(But: I'm not sure that you can safely call ContainsKey while some other thread is call Add. So it might not be possible to avoid the lock at all.)
If you just want to avoid the Thingy is created but not used, just create it within the locking block:
private Dictionary<string, Thingey> Thingeys;
public Thingey GetThingey(Request request)
{
string thingeyName = request.ThingeyName;
if (!this.Thingeys.ContainsKey(thingeyName))
{
lock (this.Thingeys)
{
// only one can create the same Thingy
Thingey newThingey = new Thingey(request);
if (!this.Thingeys.ContainsKey(thingeyName))
{
this.Thingeys.Add(thingeyName, newThingey);
}
}
}
return this. Thingeys[thingeyName];
}
You have to ask yourself the question whether the specific ContainsKey operation and the getter are themselfes threadsafe (and will stay that way in newer versions), because those may and willbe invokes while another thread has the dictionary locked and is performing the Add.
Typically, .NET locks are fairly efficient if used correctly, and I believe that in this situation you're better of doing this:
bool exists;
lock (thingeys) {
exists = thingeys.TryGetValue(thingeyName, out thingey);
}
if (!exists) {
thingey = new Thingey();
}
lock (thingeys) {
if (!thingeys.ContainsKey(thingeyName)) {
thingeys.Add(thingeyName, thingey);
}
}
return thingey;
Well I hope not being to naive at giving this answer. but what I would do, as Thingyes are expensive to create, would be to add the key with a null value. That is something like this
private Dictionary<string, Thingey> Thingeys;
public Thingey GetThingey(Request request)
{
string thingeyName = request.ThingeyName;
if (!this.Thingeys.ContainsKey(thingeyName))
{
lock (this.Thingeys)
{
this.Thingeys.Add(thingeyName, null);
if (!this.Thingeys.ContainsKey(thingeyName))
{
// create a new thingey on 1st reference
Thingey newThingey = new Thingey(request);
Thingeys[thingeyName] = newThingey;
}
// else - oops someone else beat us to it
// but it doesn't mather anymore since we only created one Thingey
}
}
return this.Thingeys[thingeyName];
}
I modified your code in a rush so no testing was done.
Anyway, I hope my idea is not so naive. :D
You might be able to buy a little bit of speed efficiency at the expense of memory. If you create an immutable array that lists all of the created Thingys and reference the array with a static variable, then you could check the existance of a Thingy outside of any lock, since immutable arrays are always thread safe. Then when adding a new Thingy, you can create a new array with the additional Thingy and replace it (in the static variable) in one (atomic) set operation. Some new Thingys may be missed, because of race conditions, but the program shouldn't fail. It just means that on rare occasions extra duplicate Thingys will be made.
This will not replace the need for duplicate checking when creating a new Thingy, and it will use a lot of memory resources, but it will not require that the lock be taken or held while creating a Thingy.
I'm thinking of something along these lines, sorta:
private Dictionary<string, Thingey> Thingeys;
// An immutable list of (most of) the thingeys that have been created.
private string[] existingThingeys;
public Thingey GetThingey(Request request)
{
string thingeyName = request.ThingeyName;
// Reference the same list throughout the method, just in case another
// thread replaces the global reference between operations.
string[] localThingyList = existingThingeys;
// Check to see if we already made this Thingey. (This might miss some,
// but it doesn't matter.
// This operation on an immutable array is thread-safe.
if (localThingyList.Contains(thingeyName))
{
// But referencing the dictionary is not thread-safe.
lock (this.Thingeys)
{
if (this.Thingeys.ContainsKey(thingeyName))
return this.Thingeys[thingeyName];
}
}
Thingey newThingey = new Thingey(request);
Thiney ret;
// We haven't locked anything at this point, but we have created a new
// Thingey that we probably needed.
lock (this.Thingeys)
{
// If it turns out that the Thingey was already there, then
// return the old one.
if (!Thingeys.TryGetValue(thingeyName, out ret))
{
// Otherwise, add the new one.
Thingeys.Add(thingeyName, newThingey);
ret = newThingey;
}
}
// Update our existingThingeys array atomically.
string[] newThingyList = new string[localThingyList.Length + 1];
Array.Copy(localThingyList, newThingey, localThingyList.Length);
newThingey[localThingyList.Length] = thingeyName;
existingThingeys = newThingyList; // Voila!
return ret;
}