示例#1
0
        public static (Guid JobId, DateTime StartTime, Task Task) StartNewJob(BaseJob job)
        {
            var dbJob = new Job {
                Id = Guid.NewGuid(), StartTime = DateTime.UtcNow, RelatedEntity = job.RelatedEntityId, Description = job.Description, Status = JobStatus.Running
            };

            using (var ctx = new DataContext())
            {
                ctx.Jobs.Add(dbJob);
                ctx.SaveChanges();
                ctx.Entry(dbJob).State = EntityState.Detached;
            }

            if (!_activeJobs.TryGetValue(dbJob.RelatedEntity, out var jobList))
            {
                _activeJobs.Add(dbJob.RelatedEntity, new List <Job>());
            }

            _activeJobs[dbJob.RelatedEntity].Add(dbJob);

            Task task      = null;
            bool taskSetup = false;

            _ = Task.Run(async() =>
            {
                using (var ctx = new DataContext())
                {
                    ctx.Jobs.Attach(dbJob);
                    job.ReportError = async x => await SaveError(x, dbJob, ctx);
                    taskSetup       = true;
                    task            = job.JobTask();

                    while (!task.IsCompleted)
                    {
                        dbJob.Heartbeat = DateTime.UtcNow;
                        await ctx.SaveChangesAsync();

                        await Task.Delay(1000);
                    }
                    if (task.IsFaulted)
                    {
                        await SaveError(task.Exception.GetBaseException().Message, dbJob, ctx);
                        dbJob.Status = JobStatus.Error;
                    }
                    else if (dbJob.Errors != null)
                    {
                        dbJob.Status = JobStatus.FinishedWithErrors;
                    }
                    else
                    {
                        dbJob.Status = JobStatus.Finished;
                    }

                    await ctx.SaveChangesAsync();
                    _activeJobs[dbJob.RelatedEntity].Remove(dbJob);
                    if (!_activeJobs[dbJob.RelatedEntity].Any())
                    {
                        _activeJobs.Remove(dbJob.RelatedEntity);
                    }
                }
            });

            while (!taskSetup)
            {
                Task.Delay(10).GetAwaiter().GetResult();
            }

            return(dbJob.Id, dbJob.StartTime, task);
        }