-
-
Notifications
You must be signed in to change notification settings - Fork 837
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Threading issue in LifeTimeScope.GetOrCreateAndShare #666
Comments
Can you please provide a repro and post it somewhere? Given many people are successfully using Autofac with WCF and not seeing this error, we'll need to see it ourselves in order to troubleshoot. |
I have rewrited method:GetOrCreateAndShare, added check for key, and it it works now. public object GetOrCreateAndShare(Guid id, Func<object> creator)
{
if (creator == null)
{
throw new ArgumentNullException("creator");
}
lock (_synchRoot)
{
object result;
if (!_sharedInstances.TryGetValue(id, out result))
{
result = creator();
lock (_synchRoot)
{
if (!_sharedInstances.ContainsKey(id))
_sharedInstances.Add(id, result);
}
}
return result;
}
} |
A unit test showing the issue along with the fix would be best. Wondering what exactly the cause is and a screen capture isn't something we can execute to understand the problem. |
Dictionary is not thread safe, so it should be double checked, I think |
I think I see the problem. I'll take a look. I suspect we should also prevent the creator function from being invoked a second time too, even if the second lock prevents the instance from being added to the dictionary. |
I'm guessing the ContainsKey call is what made the difference (though it escapes me how, since it should have been covered by the try-get). The second/nested lock won't have any effect on the use of the dictionary because no other threads can get into that critical section while the outer lock is held. |
reproduced in unit test: |
This isn't a threading issue at all. The problem is that while creating an instance of A, you are invoking a factory during its construction that creates another instance of A. The factory generated A gets added to the dictionary because its first to complete creation, and when the original A is finally being added to the dictionary it's too late. We don't detect this in the circular dependency check because the initial and pending activation of A hasn't yet completed. Your second unit test passes because when B is created first, it creates the instance of A via the factory, and when it then requests A as its second constructor parameter, the instance already exists and no attempt to create it is made. The code change you made basically allows a second instance to be created even though you are only supposed to receive one per lifetime scope (A is configured as |
…LifetimeScope service attempts to create an instance of itself during its construction.
I have updated LifetimeScope to throw a DependencyResolutionException with the message below:
That should be more helpful than the dictionary exception. |
I have WCF service, and on method calls I get exception:
as I investigated sources such error can't happen, because it checks before add.
The text was updated successfully, but these errors were encountered: