locked
DbContext and multiple threads RRS feed

  • Question

  • Hello,

    we are using CTP5 together with Workflow Foundation - in our scenario it means multiple DbContext instances in multiple threads (and multiple exceptions ;-).

    To reproduce theese exception we've done the following:

    1.) Our business object:

    public class Data
    {
     public int Id { get; set; }
     public string Text { get; set; }
    }
    

    2.) Our DbContext:

    public class Context : DbContext
    {
     public Context(string connectionString)
      : base(connectionString)
     {}
     public DbSet<Data> Datas { get; set; }
    }
    

    3.) Our code:

    Parallel.ForEach(Enumerable.Range(1, 10), i =>
    {
     using (Context context = new Context("Data Source=(local);Initial Catalog=EFTEST;Integrated Security=true"))
     {
     Console.WriteLine("{0}: {1}", i, context.Datas.Where(d => d.Id % i == 0).Count());
     }
    });
    

    This results in an System.AggregateException.

    Encapsulation the new Context(...) line with a lock statement is no solution - the exception still appears. The model creation seems to be a async operation.

    For now we solves the problem with a dirty trick:

    public class Context : DbContext
    {
     private static readonly object locker = new object();
     public Context(string connectionString)
      : base(connectionString)
     {
     lock (locker)
     {
      this.ChangeTracker.DetectChanges();
    } } public DbSet<Data> Datas { get; set; } }

    What is the right strategy for this problem ?

    Best regards Matthias

    Wednesday, February 9, 2011 9:21 PM

Answers

  • Hi Matthias,

    In CTP5 model creation doesn't have any logic to deal with multiple threads potentially initializing the model. This will be fixed for RTM, your workaround is fine, although I would probably call this.Database.Initialize(force: false); rather than DetectChanges.

    ~Rowan

    Wednesday, February 9, 2011 10:28 PM
    Moderator

All replies

  • Hi Matthias,

    In CTP5 model creation doesn't have any logic to deal with multiple threads potentially initializing the model. This will be fixed for RTM, your workaround is fine, although I would probably call this.Database.Initialize(force: false); rather than DetectChanges.

    ~Rowan

    Wednesday, February 9, 2011 10:28 PM
    Moderator
  • Thanks for your advice. It works well. ~Matthias
    Thursday, February 10, 2011 8:49 AM