Threadsafe DBContext in singleton 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&lt;Thread, MyContext&gt; contexts = new ConditionalWeakTable&lt;Thread, MyContext&gt;();

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?
General rules of thumb:


In order to take advantage of connection pooling (and you should), database connections should be as short lived as possible. Create, use, then immediately destroy.
Single instance objects should always be agile (defined as not holding system resources e.g. db connections, file handles, etc.).
If you need a single instance object to handle a system resource, it should be done in a protected manner using a named mutex (naming makes a mutex available to all threads across the computer) or Monitor. Within the protected block of code, if the resource is a db connection, apply rule 1.
When using object locking, you should create your locks around an arbitrary object, not the current object's instance e.g.:

private static readonly object _lockObject = new object();


...

try {
    Monitor.Enter(_lockObject);
    // Do protected stuff...
}
finally {
    Monitor.Exit(_lockObject);
}