如何在实体框架中使用TPL?

时间:2014-07-17 13:04:44

标签: .net entity-framework task-parallel-library

我期待将TPL与Entity Framework 6.1结合使用。我已用此编码了演示应用程序;

解释我想要实现的目标:

代码:

     public void StoreTeamDetailsFromServer()
        {
            try
            {
                IAccountRepository accountRepository = new AccountRepository();
                var userDetails = accountRepository.GetLoggedInUserDetails();

                int pageSize = 10;

                var departmentApiParams = new
                {
                    username= userDetails.UserName,
                    password= userDetails.Password,
                    sort_by = "a-z",
                    filter_by = "all",
                    n_records = pageSize,
                    index_from = 1 

                };

                /* Generic Code Repository to get my details for JSON RPC */

                JsonRpcRequest getDepartmentDetailsRequestParams = new JsonRpcRequest() { ApiMethod = "department_list", Params = departmentApiParams, Url = "http://ServerAddress/index.php" };

                JsonWebRequestRpcRepository<DepartmentWrapper> jsonRpcClientRepository = new JsonWebRequestRpcRepository<DepartmentWrapper>();


                /* Actual call to my Generic JSON RPC Repository */

                var departmentResponse = jsonRpcClientRepository.RpcCall(getdepartmentDetailsRequestParams).Response;
                /* This is the Task which is created to Start saving the data of the First Page*/

                Task departmentTasks =  Task.Run(() => SaveDepartments(Mapper.Map<List<DepartmentResponse>, List<Departments>>(departmentResponse.departmentDetails)));
                /* This is where it queries it the Result has more Records i.e. more Pages */

                if (departmentResponse.HasMoreRecords)
                {
                    /* This is where the Paging logic is taking place  */

                    int totalRecords = departmentResponse.TotalCount;
                    int totalPages = Convert.ToInt32(Math.Ceiling((decimal)totalRecords / pageSize));
                    for (int page = 0; page < totalPages; page++)
                    {

                        /* This is calculated for the next page request formation */
                        var currentIndex = departmentResponse.DepartmentDetails.Max(x => x.Index);

                      /* This is where the Task is getting created Repeated for saving the further pages in the data */
                        departmentResponse = jsonRpcClientRepository.RpcCall(GetJsonRpcDepartmentParams(userDetails.UserName,userDetails.Password,currentIndex,pageSize)).Response;
                        departmentTasks = Task.Run(() =>  SaveDepartments(Mapper.Map<List<DepartmentResponse>, List<Departments>>(departmentResponse.DepartmentDetails)));

                    }

                }
                Console.WriteLine(DepartmentResponse.TotalCount + " Departments added into the Database");

            }
            catch
            {
                throw;
            }

        }

       private void SaveDepartments(List<Departments> departmentList)
       {
        try
        {
            IDepartmentRepository DepartmentRepository = new DepartmentRepository();

            DepartmentRepository.AddOrUpdateDepartments(departmentList);
        }
        catch
        {
            throw;
        }
      }

我有一个Web JSON-RPC调用,它为我提取数据。现在这个数据被分页,我想用它来获取数据 - 启动TASK(TPL)来保存数据 - 同时调用数据的下一页(再次返回时会启动一个任务来保存数据)数据)。

现在,发生的事情是,任务创建等工作正常,数据也开始得到保存。但是,最后一页的问题出现了,在DepartmentRepository中传递的数据。 Console.WriteLine(“”)首先覆盖,然后任务用于保存数据。

理想情况下,根据我发生的事情是“上下文”,即我执行任务的数据因为执行超出范围而丢失了。

处理此问题的最佳方式是什么?

1 个答案:

答案 0 :(得分:2)

问题是您在退出之前没有等待所有任务完成。此外,在重新使用departmentTasks变量时,您不会保留对每个任务的引用。

相反,请保留您开始执行的所有任务的列表,并在结尾处记录WaitAll()。所以你的方法变成:

public void StoreTeamDetailsFromServer()
{
    try
    {
        IAccountRepository accountRepository = new AccountRepository();
        var userDetails = accountRepository.GetLoggedInUserDetails();

        int pageSize = 10;

        var departmentApiParams = new
        {
            username= userDetails.UserName,
            password= userDetails.Password,
            sort_by = "a-z",
            filter_by = "all",
            n_records = pageSize,
            index_from = 1 
        };

        /* Generic Code Repository to get my details for JSON RPC */

        JsonRpcRequest getDepartmentDetailsRequestParams = new JsonRpcRequest() { ApiMethod = "department_list", Params = departmentApiParams, Url = "http://ServerAddress/index.php" };

        JsonWebRequestRpcRepository<DepartmentWrapper> jsonRpcClientRepository = new JsonWebRequestRpcRepository<DepartmentWrapper>();


        /* Actual call to my Generic JSON RPC Repository */

        var departmentResponse = jsonRpcClientRepository.RpcCall(getdepartmentDetailsRequestParams).Response;
        /* This is the Task which is created to Start saving the data of the First Page*/

        List<Task> allTasks = new List<Task>();

        allTasks.Add(Task.Run(() => SaveDepartments(Mapper.Map<List<DepartmentResponse>, List<Departments>>(departmentResponse.departmentDetails))));

        if (departmentResponse.HasMoreRecords)
        {
            int totalRecords = departmentResponse.TotalCount;
            int totalPages = Convert.ToInt32(Math.Ceiling((decimal)totalRecords / pageSize));
            for (int page = 0; page < totalPages; page++)
            {
                /* This is calculated for the next page request formation */
                var currentIndex = departmentResponse.DepartmentDetails.Max(x => x.Index);

                departmentResponse = jsonRpcClientRepository.RpcCall(GetJsonRpcDepartmentParams(userDetails.UserName,userDetails.Password,currentIndex,pageSize)).Response;
                allTasks.Add(Task.Run(() =>  SaveDepartments(Mapper.Map<List<DepartmentResponse>, List<Departments>>(departmentResponse.DepartmentDetails))));

            }

        }

        //Now we wait for all tasks to complete
        Task.WaitAll(allTasks.ToArray());

        Console.WriteLine(DepartmentResponse.TotalCount + " Departments added into the Database");

    }
    catch
    {
        throw;
    }

}