示例#1
0
        /// <summary>
        /// 开始执行简单任务
        /// </summary>
        /// <param name="interval">时间间隔(毫秒)</param>
        /// <param name="continued">是否持续执行</param>
        /// <param name="doWhat"></param>
        /// <param name="workerName"></param>
        /// <param name="description"></param>
        public static void Do(double interval, bool continued = true, Action <SpareTimer, long> doWhat = default, string workerName = default, string description = default)
        {
            if (string.IsNullOrWhiteSpace(workerName) || doWhat == null)
            {
                return;
            }

            // 创建定时器
            var timer = new SpareTimer(interval, workerName)
            {
                Type        = SpareTimeTypes.Interval,
                Description = description,
                Status      = SpareTimeStatus.Running
            };

            // 订阅执行事件
            timer.Elapsed += (sender, e) =>
            {
                // 获取当前任务的记录
                _ = WorkerRecords.TryGetValue(workerName, out var currentRecord);

                // 停止任务
                if (!continued)
                {
                    Cancel(timer.WorkerName);
                }

                // 记录执行次数
                currentRecord.Tally += 1;

                // 处理多线程并发问题(重入问题)
                var interlocked = currentRecord.Interlocked;
                if (Interlocked.Exchange(ref interlocked, 1) == 0)
                {
                    // 更新任务记录
                    UpdateWorkerRecord(workerName, currentRecord);

                    // 执行任务
                    doWhat(timer, currentRecord.Tally);

                    // 处理重入问题
                    Interlocked.Exchange(ref interlocked, 0);
                }
            };

            timer.AutoReset = continued;
            timer.Start();
        }
示例#2
0
        /// <summary>
        /// 开始执行简单任务
        /// </summary>
        /// <param name="intervalHandler">时间间隔(毫秒)</param>
        /// <param name="doWhat"></param>
        /// <param name="workerName"></param>
        /// <param name="description"></param>
        /// <param name="startNow"></param>
        /// <param name="cancelInNoneNextTime"></param>
        /// <param name="executeType"></param>
        /// <param name="continued">是否持续执行</param>
        public static void Do(Func <double> intervalHandler, Action <SpareTimer, long> doWhat = default, string workerName = default, string description = default, bool startNow = true, bool cancelInNoneNextTime = true, SpareTimeExecuteTypes executeType = SpareTimeExecuteTypes.Parallel, bool continued = true)
        {
            if (doWhat == null)
            {
                return;
            }

            // 自动生成任务名称
            workerName ??= Guid.NewGuid().ToString("N");

            // 获取执行间隔
            var interval = intervalHandler();

            // 判断是否在下一个空时间取消任务
            if (cancelInNoneNextTime)
            {
                if (interval <= 0)
                {
                    Cancel(workerName);
                    return;
                }
            }
            else
            {
                if (interval <= 0)
                {
                    return;
                }
            }

            // 创建定时器
            var timer = new SpareTimer(interval, workerName)
            {
                Type        = SpareTimeTypes.Interval,
                Description = description,
                Status      = startNow ? SpareTimeStatus.Running : SpareTimeStatus.Stopped,
                ExecuteType = executeType
            };

            // 订阅执行事件
            timer.Elapsed += async(sender, e) =>
            {
                // 获取当前任务的记录
                _ = WorkerRecords.TryGetValue(workerName, out var currentRecord);

                // 处理串行执行问题
                if (timer.ExecuteType == SpareTimeExecuteTypes.Serial)
                {
                    if (!currentRecord.IsCompleteOfPrev)
                    {
                        return;
                    }

                    // 立即更新多线程状态
                    currentRecord.IsCompleteOfPrev = false;
                    UpdateWorkerRecord(workerName, currentRecord);
                }

                // 记录执行次数
                currentRecord.Timer.Tally = currentRecord.Tally += 1;

                // 处理多线程并发问题(重入问题)
                var interlocked = currentRecord.Interlocked;
                if (Interlocked.Exchange(ref interlocked, 1) == 0)
                {
                    try
                    {
                        // 执行任务
                        doWhat(timer, currentRecord.Tally);
                    }
                    catch (Exception ex)
                    {
                        // 记录任务异常
                        currentRecord.Timer.Exception.TryAdd(currentRecord.Tally, ex);

                        // 如果任务执行超过 10 次失败,则停止任务
                        if (currentRecord.Timer.Exception.Count > 10)
                        {
                            Stop(workerName, true);
                        }
                    }
                    finally
                    {
                        // 处理串行执行问题
                        currentRecord.IsCompleteOfPrev = true;

                        // 更新任务记录
                        UpdateWorkerRecord(workerName, currentRecord);
                    }

                    // 如果间隔小于或等于 0 取消任务
                    if (interval <= 0)
                    {
                        Cancel(workerName);
                    }

                    // 停止任务
                    if (!continued)
                    {
                        Cancel(workerName);
                    }

                    // 处理重入问题
                    Interlocked.Exchange(ref interlocked, 0);

                    await Task.CompletedTask;
                }
            };

            timer.AutoReset = continued;
            if (startNow)
            {
                timer.Start();
            }
        }