예제 #1
0
        private Action CreateTaskBody(TaskExecutionInfo executionInfoLocal, TaskTypeInfo taskTypeInfo)
        {
            return(() =>
            {
                try
                {
                    executionInfoLocal.SendAliveSignal();
                    executionInfoLocal.SetTaskThread(Thread.CurrentThread);

                    if (executionInfoLocal.CancellationTokenSource.IsCancellationRequested)
                    {
                        return;
                    }

                    if (!SetRunningStatus(executionInfoLocal, taskTypeInfo))
                    {
                        return;
                    }

                    executionInfoLocal.SendAliveSignal();

                    //Flags executionInfoLocal right before invoking the task implementation
                    executionInfoLocal.RealTaskInvokedFlag = true;
                    taskTypeInfo.Invoke(executionInfoLocal.TaskDefinition.JsonParameters, executionInfoLocal);

                    SetCompletedOrCancelledStatus(executionInfoLocal);
                }
                catch (ThreadAbortException ex)
                {
                    //Tries to save information about the task status.
                    //Reverts ThreadAbort
                    Thread.ResetAbort();

                    SetAbortedStatus(executionInfoLocal);
                }
                catch (Exception ex)
                {
                    ex.LogException();

                    SetCompletedOrCancelledStatus(executionInfoLocal);
                }
                finally
                {
                    try
                    {
                        //See comment below
                        executionInfoLocal.LockWillBeReleasedFlag = true;
                        _taskManager.LockManager.Release(executionInfoLocal.LockInfo);

                        //**** LockWillBeReleasedFlag avoids having the task being aborted right here when it's about to end, because we just released the lock
                        // and the lifetime manager could try to cancel it forcefully.
                    }
                    catch (Exception ex)
                    {
                        ex.LogException();
                    }
                }
            });
        }
        internal void Invoke(string jsonParameter, TaskExecutionInfo executionInfo)
        {
            object parameter = null;

            if (jsonParameter != null)
            {
                parameter = JsonConvert.DeserializeObject(jsonParameter, this.ParamType);
            }

            var instance = Activator.CreateInstance(this.TaskType);

            TaskTypeInfo.TypedInvoke((dynamic)instance, (dynamic)parameter, executionInfo);
        }
        private TaskTypeInfo CreateTaskInfo(Type type, TaskSettings settings)
        {
            Type paramType   = null;
            var  genericType = GetGenericTaskType(type, out paramType);

            if (genericType == null)
            {
                throw new ApplicationException(String.Format("The type [{0}] is not a valid Task or Task<P> type.", type.FullName));
            }

            TaskTypeInfo info = TaskTypeInfo.CreateFromType(type, paramType, settings);

            return(info);
        }
예제 #4
0
        private bool SetRunningStatus(TaskExecutionInfo executionInfoLocal, TaskTypeInfo taskTypeInfo)
        {
            var lockInfo       = executionInfoLocal.LockInfo;
            var taskDefinition = executionInfoLocal.TaskDefinition;

            //It may be that the task scheduler took too long to start the thread.
            //Renews the lock. Ignores the task if it doesn't acquire lock
            if (!_taskManager.LockManager.TryRenewLock(lockInfo, taskTypeInfo.LockCycle, retryLock: true))
            {
                return(false);
            }

            using (var tr = new TransactionScope(TransactionScopeOption.Suppress, TransactionScopeAsyncFlowOption.Enabled))
                using (var conn = _taskManager.CreateConnection())
                    using (var command = DbAccessHelper.CreateDbCommand(conn, SET_RUNNING_STATUS_SQL))
                    {
                        //milisecond precision
                        var lastRunAt = _taskManager.GetUtcNow().SetFractionalSecondPrecision(3);
                        var lockState = lockInfo.AsImmutable();

                        command.Parameters.Add(new SqlParameter("Id", taskDefinition.Id));
                        command.Parameters.Add(new SqlParameter("LastRunAt", System.Data.SqlDbType.DateTime2)
                        {
                            Value = lastRunAt
                        });
                        command.Parameters.Add(new SqlParameter("LockedUntil", System.Data.SqlDbType.DateTime2)
                        {
                            Value = lockState.LockedUntil
                        });

                        //Has the task been deleted or already handled?
                        if (command.ExecuteNonQuery() != 1)
                        {
                            return(false);
                        }

                        executionInfoLocal.LastRunAt = lastRunAt;

                        return(true);
                    }
        }