Does thread scope in ninject creates new dbcontext on every thread call

假如想象 提交于 2019-12-24 11:28:05

问题


I have configured ninject in wep api as below. I have created two kernel objects, one in request scope and another in thread scope:

var requestKernel = new StandardKernel();
requestKernel.Bind<IGlobalDbContext>().ToConstructor(ctx => new GlobalDbContext(Configuration.GlobalDbContext)).InRequestScope();

var threadKernel = new StandardKernel();
RegisterServices(threadKernel);
threadKernel.Bind<IGlobalDbContext>().ToConstructor(ctx => new GlobalDbContext(Configuration.GlobalDbContext)).InThreadScope();
new Kernel(threadKernel);

Here new Kernel is a class for creating thread scope DBContext:

public class Kernel
{
    private static StandardKernel _kernel = null;

    public Kernel(StandardKernel kernel)
    {
        if (_kernel == null)
        {
            _kernel = kernel;
        }
    }

    public static IKernel GetKernel
    {
        get
        {
            return _kernel;
        }
    }
}

Now I have created two tasks in below action methods:

[HttpPost]
public void RunThreadrequest()
{
    ThreadFactory threadFactory = new ThreadFactory();
    DateTime fromDate = Convert.ToDateTime("2018-05-01");
    DateTime toDate = Convert.ToDateTime("2018-05-31");
    List<int> orders = _orderManager.All().Where(o => o.IsActive && (o.DeliveryDate >= fromDate && o.DeliveryDate <= toDate)).Select(o => (int)o.Id).ToList();
    int length = 2;
    int i = 0;
    int startIndex = 0;
    int endIndex = orders[0] - 1;
    do
    {
        startIndex = endIndex + 1;
        endIndex = startIndex + 5;
        OrderIndex ordIndexObj = new OrderIndex { StartIndex = startIndex, EndIndex = endIndex };
        threadFactory.CreateThread((ordIndex) =>
        {
            ParameterConfigurationController controller =  (ParameterConfigurationController)(Kernel.GetKernel.GetService(typeof(ParameterConfigurationController)));
            controller.UpdateOrders(((OrderIndex)ordIndex).StartIndex, ((OrderIndex)ordIndex).EndIndex);
        }, ordIndexObj);
        i++;
    } while (i < length);
    threadFactory.Run();
}

public struct OrderIndex
{
    public int StartIndex { get; set; }
    public int EndIndex { get; set; }
    public int ThreadId { get; set; }
    public int Index { get; set; }
}

The above code will create two thread and call the method UpdateOrders:

public void UpdateOrders(int startIndex, int lastIndex)
{
    var orders = _orderManager.All().Where(o => o.Id >= startIndex && o.Id <= lastIndex).ToList();
    foreach (Order order in orders)
    {
        order.StatusId = 11;
    }      
    _orderManager.SaveChanges();
}

Thread code:

class ThreadFactory
{
    private List<Task> threads = new List<Task>();
    private CancellationTokenSource source = new CancellationTokenSource();
    private CancellationToken token;
    public ThreadFactory()
    {
        token = source.Token;
    }

    public void CreateThread(Action<object> action, OrderIndex ordObj)
    {
        if (token.IsCancellationRequested)
            token.ThrowIfCancellationRequested();
        Task task = Task.Factory.StartNew(action, ordObj, token);
        threads.Add(task);
    }

    public void Run()
    {
        Task.WaitAll(this.threads.ToArray());
    }
}

What I observed is: when SaveChanges is called in one thread and I refresh the database no records are effected with status 11. When second thread done its execution then the records gets effected.

My question is,

1) does InThreadScope() creates one dbcontext per thread or multiple dbcontext?

2) Is there any transaction maintained by Task.WaitAll so that all the threads execution will be committed at once

Please suggest, if I am missing anything.

来源:https://stackoverflow.com/questions/51880046/does-thread-scope-in-ninject-creates-new-dbcontext-on-every-thread-call

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!