Beispiel #1
0
        protected async Task Run(Job job, IServiceScope scope)
        {
            var jobService       = scope.ServiceProvider.GetRequiredService <IJobService>();
            var procedureService = scope.ServiceProvider.GetRequiredService <IProcedureService>();
            var contextFactory   = scope.ServiceProvider.GetRequiredService <IContextFactory>();

            var log     = new JobLogger(_logger, job);
            var cts     = new CancellationTokenSource();
            var context = contextFactory.Create(job, log, cts.Token, p => job.Progress = p);

            jobService.RegisterCanceller(job.Id, () => cts.Cancel(true));

            await Task.Factory.StartNew(() =>
            {
                job.StartAt = DateTime.UtcNow;
                job.Status  = JobStatus.Running;
                try
                {
                    var procedure = procedureService.Resolve(job.Name);
                    procedure.ExecuteAsync(context).Wait(context.CancellationToken);
                }
                catch (Exception ex)
                {
                    var baseEx = ex.GetBaseException();
                    if (baseEx.GetType() == typeof(OperationCanceledException))
                    {
                        log.LogInformation("<< The job has been canceled. >>");
                        ExceptionDispatchInfo.Capture(baseEx).Throw();
                    }
                    else
                    {
                        log.LogError(ex, ex.Message);
                        context.Errors.Add(new Error(ERR_EXCEPTION_THROWN));
                    }
                }
            }, context.CancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Default)
            .ContinueWith(t =>
            {
                foreach (var error in context.Errors)
                {
                    log.LogError(error.ToString());
                }
                job.FinishAt = DateTime.UtcNow;

                if (t.IsCanceled)
                {
                    job.Status = JobStatus.Canceled;
                }
                else
                {
                    job.Progress = 100;
                    job.Status   = context.Errors.Count == 0 ? JobStatus.Success : JobStatus.Faild;
                }
                jobService.SaveAsync(job).Wait(context.CancellationToken);
            });
        }