Getting exception with executing multiple function parallel using Task.Run, Entity Framework 6.0, Generic Repo, UOW

Dec 2, 2014 at 1:13 PM
Edited Dec 4, 2014 at 6:25 AM
We are using WebAPI and Entity Framework 6.0 + generic repository and UOW for our new project. The issue we are facing is I have 20 methods which I am running parallel using Task.Run. Some of these method have call to database. Thats why we are getting below exception
The context cannot be used while the model is being created. This exception may be thrown if the context is used inside the OnModelCreating method or if the same context instance is accessed by multiple threads concurrently. Note that instance members of DbContext and related classes are not guaranteed to be thread safe.
Below is my code sample:

1) Base class for Created for context
public class DataContext : DbContext, IDataContext
    {
        public DataContext(string nameOrConnectionString)
            : base(nameOrConnectionString)
        {            
        }

        public new DbSet<T> Set<T>() where T : class
        {
            return base.Set<T>();
        }
   }
2) Base class inherited that class with Context class :
public partial class TestContext : DataContext
    {
        static TestContext()
        {
            Database.SetInitializer<TestContext>(null);
        }
        public TestContext() : base("Name=ConnStr")
        {}
        public DbSet<User> Users { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
          modelBuilder.Configurations.Add(new UserMap());          
        }
    }
2) Generic repository :: which accepts type of class entity
 public class Repository<TEntity> : IRepository<TEntity> where TEntity : BaseEntity
    {
        private readonly IDataContext context;
        private readonly DbSet<TEntity> databaseSet;

        public Repository(IDataContext context)
        {            
            this.context = context;
            databaseSet = context.Set<TEntity>();        
        }

        public IQueryable<TEntity> Get()
        {
            IQueryable<TEntity> query = databaseSet;
            return query;
        }
    }
My service class call this Repository.Get method to get data.

I am using NInject to create instance
this.Bind<IDataContext>().To<TestContext>();
Any help or new suggestion will really appreciated !!!
Coordinator
Dec 2, 2014 at 1:42 PM
Edited Dec 2, 2014 at 1:44 PM
Please post the complete Ninject binding configuration along with container configuration and some sample TPL implementation code that mirrors your implementation, this sounds more of a multi-threading (safe) issue which is common than anything.
Dec 3, 2014 at 6:23 AM
Edited Dec 3, 2014 at 7:55 AM
Thanks for reply!!

I am not sure which code you want as part of Ninject binding . Below is my code for that
private static readonly Bootstrapper Bootstrapper = new Bootstrapper();

        public static void Start()
        {
            DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
            DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
            Bootstrapper.Initialize(CreateKernel);
        }

        public static void Stop()
        {
            Bootstrapper.ShutDown();
        }

        private static IKernel CreateKernel()
        {
            var kernel = new StandardKernel();
            try
            {
                kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
                kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();

                RegisterServices(kernel);
                var resolver = new NinjectResolver(kernel);
                GlobalConfiguration.Configuration.DependencyResolver = resolver;
                return kernel;
            }
            catch
            {
                kernel.Dispose();
                throw;
            }
        }

        private static void RegisterServices(IKernel kernel)
        {   
            kernel.Bind<IDataContext>().To<TestContext>();           
            kernel.Bind<IRepository<User>>().To<Repository<User>>();
            kernel.Bind<IUserRepository>().To<UserRepository>();

        }
Below is my TPL implementation.
List<Task<List<string>>> tasks = new List<Task<List<string>>>();

                tasks.Add(Task.Run(() => Task1()));
                tasks.Add(Task.Run(() => Task2()));
                tasks.Add(Task.Run(() => Task3()));
                tasks.Add(Task.Run(() => Task4()));
                tasks.Add(Task.Run(() => Task5()));
                tasks.Add(Task.Run(() => Task6()));
                tasks.Add(Task.Run(() => Task7()));
                tasks.Add(Task.Run(() => Task8()));

                Task.WaitAll(tasks.ToArray());

                foreach (var task in tasks)
                {
                    response.AddErrorRange(task.Result);
                }
What needs to change in Ninject configuration to use use new fresh object for each thread. Please let me know if you require more details
Dec 4, 2014 at 10:52 AM
Can anyone please help on this
Dec 9, 2014 at 6:23 PM
Edited Dec 10, 2014 at 9:49 AM
Try to use kernel.Bind<IDataContext>().To<TestContext>().InThreadScope()
This will give you new TestContext for each thread.
Marked as answer by lelong37 on 12/19/2014 at 5:53 PM