I found out the hardway that access to DbContext in .NET is not threadsafe. I have a singleton for logging things using a dbcontext. The original version uses something like
public Logger{
private MyContext context;
private static Logger instance = new Logger();
private Logger(){
//init stuff, including context
}
public static Logger Instance {
return this.instance;
}
public void someMethod(){
//do something with this.context
}
}
I'm thinking of a few solutions:
one would be is not making this a singleton at all, but instantiate a logger each time I need one.
I can think of added overhead as a disadvantage for this way, and simplicity as an advantage.
another one is locking (on the context or type) for each public method:
public void someMethod(){
lock(this.context){
//do something with this.context
}
}
This adds extra maintenance complexity.
a third one could be one context per thread in a form of
private ConditionalWeakTable<Thread, MyContext> contexts = new ConditionalWeakTable<Thread, MyContext>();
private MyContext Context{
get {
return contexts.GetValue(Thread.CurrentThread, createContext());
}
}
private MyContext createContext(){
//instantiate a context
}
- Pro: fairly consice, complexity is isolated
- Con: batshit insane? Using
System.Runtime.CompilerServices
for something fairly mondaine, which also isn't what it's meant for.
Am I overlooking any arguments? What would you do?