间歇性地在多线程环境中获取firstofDefault()时出错

时间:2015-12-30 05:59:31

标签: c# .net multithreading entity-framework linq

我们有一个报告调度程序引擎,它是一个Windows服务,它将从DB中选择计划在一天中的特定时间生成的报告详细信息(查询,参数等),并运行查询以生成报告。

(首先使用MySQL数据库的EF5代码)

这是它的工作原理:

  1. 有一个MSMQ队列,它将具有由轮询服务提取的报告的ID。
  2. 计划报告生成器将查看报告ID的MSMQ队列,并从数据库中选择报告详细信息并生成报告。
  3. 整个过程一直运作到周五早上。我们现在有2份报告,每天上午8:00和上午8:15。除了星期五之外,每天都会生成报告,当我们遇到第2步(调度程序尝试从数据库中选择报告详细信息)的异常时。

    我的代码选择报告详细信息如下:

    public void RunScheduler(DateTime dateTime)
        {
            List<ReportScheduler> schedules;
            try
            {
    
                schedules = _scheduler.PickFromMSMQToExecute();
                if (schedules == null || schedules.Count == 0) return;
    
                Parallel.ForEach(schedules, currentSchld =>
                { 
                    CreateScheduledReport(currentSchld, dateTime);
                });
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    

    这会调用一个函数:

          private void CreateScheduledReport(ReportScheduler schedule, DateTime dateTime)
            {
                _logger = new Log4netFactory().Create("ReportSchedulerService");
                Stopwatch timer = new Stopwatch();
                var schedulerLog = new ReportSchedulerLog
                {
                    SchedulerRequestID = schedule.RequestID,
                    StartDateTime = dateTime,
                    Status = "0",
                    UpdatedOn = DateTime.Now
                };
    
                timer.Start();
                var startedTime = DateTime.Now;
    
                var saveSuccess = true;
                try
                {
                    var report = _reportRepository.GetReportforScheduling(schedule.ReportID);
                    GenerateReport(report);
                }
                catch(Exception ex)
                {}
    }
    

    表“Reports”有一个userId,它有一个对“users”表的外键引用。在try块中,调用GetReportforScheduling,是调用上下文存储库的函数,如:

      public Report GetReportforScheduling(int id)
            {
                Report rpt = new Report();
                String level = String.Empty;
                try
                {
                    level = "connecting DB if closed";
                    ReConnectDatabase(context);
                    level += ",picking the report for Report ID :" + id.ToString();
                    rpt = context.Reports.Where(t => t.ReportID == id).Include(m => m.User).FirstOrDefault();
                    level += ",Picked the report successfully";
                    if (null == rpt) return new Report();
                    level += ",Fetching the parameters";
                    rpt.ReportDetails = context.ReportDetails.Where(x => x.ReportId == id).ToList();
                    rpt.HasDetail = context.ReportParameters.Any(x => x.ReportTemplateParameters.Any(t => t.TemplateId == rpt.TemplateID) && !(x.IsDynamic == "1"));
    
                    level += ",Parameters fetched";
                }
                catch (Exception ex)
                {
                    _logger.Info("Error Level :" + level);
                    _logger.Error("Error on picking the report / details from the DB :" + ex.Message, ex);
                }
                return rpt;
            }
    

    该行:

    rpt = context.Reports.Where(t => t.ReportID == id).Include(m => m.User).FirstOrDefault();
    

    在每个星期五给出问题,如果我们重新启动Windows服务,它也会像例外一样运行。提出的例外是:

      

    2015-12-25 23:59:39,703 [19] ReportScheduler.Service.exe INFO   EIS.DataAccess.Repository.ReportRepository   GetReportforScheduling - 错误级别:如果关闭,则选择连接数据库   报告编号报告:15

         

    2015-12-25 23:59:39,718 [19]   ReportScheduler.Service.exe错误   EIS.DataAccess.Repository.ReportRepository   GetReportforScheduling - 从中​​选择报告/详细信息时出错   DB:执行命令定义时发生错误。看到   细节的内在例外。

         

    EIS.Infrastructure.Logger.EISException:发生错误   在执行命令定义时。查看内部异常   细节。在   System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand   entityCommand,CommandBehavior行为)
    在   System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlan.Execute [TResultType](ObjectContext的   context,ObjectParameterCollection parameterValues)
    在   System.Data.Entity.Core.Objects.ObjectQuery 1.<>c__DisplayClassb.<GetResults>b__a()<br> at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func 1   func,IDbExecutionStrategy executionStrategy,Boolean   startLocalTransaction,Boolean releaseConnectionOnSuccess)
    在   System.Data.Entity.Core.Objects.ObjectQuery 1.<>c__DisplayClassb.<GetResults>b__9()<br> at System.Data.Entity.Infrastructure.DefaultExecutionStrategy.Execute[TResult](Func 1   操作)
    在   System.Data.Entity.Core.Objects.ObjectQuery 1.GetResults(Nullable 1   forMergeOption)
    在   System.Data.Entity.Core.Objects.ObjectQuery 1.<System.Collections.Generic.IEnumerable<T>.GetEnumerator>b__0()<br> at System.Lazy 1.CreateValue()
    at   System.Lazy 1.LazyInitValue()<br> at System.Lazy 1.get_Value()
      在System.Data.Entity.Internal.LazyEnumerator 1.MoveNext()<br> at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable 1   来源)
    在   System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.b__1 [TResult](IEnumerable的1 sequence)<br> at System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.ExecuteSingle[TResult](IEnumerable 1   查询,表达式queryRoot)
    在   System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute [TResult](式   表达)   System.Data.Entity.Internal.Linq.DbQueryProvider.Execute [TResult](式   表达)   System.Linq.Queryable.FirstOrDefault [TSource](IQueryable`1 source)
      在   EIS.DataAccess.Repository.ReportRepository.GetReportforScheduling(的Int32   id)的

    这是因为多线程环境还是延迟加载用户的上下文?

0 个答案:

没有答案