I have a WCF service .net framework 4.0 that uses Autofac.
Then I have several dependencies that are resolved like this:
builder.RegisterType<LogicA>().As<ILogicA>().InstancePerLifetimeScope();
I have an operation inside a class where a dependendy is injected via parameter because the class itself is also referenced on the same class as the dependency:
public void DoStuff(List<string> items, ILogicA logicA){
foreach (var item in items)
{
System.Threading.ThreadPool.QueueUserWorkItem(queueUserWorkItem =>
{
logicA.DoOtherStuff(item);
});
}}
What happens is that inside DoOtherStuff method, it calls other classes and some of them have state (properties) that are filled for each item on the collection and at the end data gets saved on the database.
And at the end when the items collection starts to have a few items (more than 6 or 7) sometimes I begin to receive primary key violation errors (this uses SQL server under the hood) and if I turn on an SQL profiler I can see more than 1 call for the same ID, while if I place logging at the beginning of my foreach block above I don't see anything repeated, which leads me to think that maybe this logicA parameter turns out NOT to be thread safe.
Should I resolve this dependency on demand inside my QueueUserWorkItem block or am I missing anything else here?
Thank you for any help
Hard to say without knowing more context, but this seems like a classic unit-of-work scenario, where you may want to allocate a lifetime scope for each background operation.
public void DoStuff(List<string> items, ILifetimeScope scope){
foreach (var item in items)
{
var newScope = scope.BeginLifetimeScope();
System.Threading.ThreadPool.QueueUserWorkItem(queueUserWorkItem =>
{
using (newScope)
{
var logicA = newScope.Resolve<ILogicA>();
logicA.DoOtherStuff(item);
}
});
}}
Even if that's not exactly right, it's often wise not to share a single lifetime scope across any units of work; shared state can get a little weird.