Beispiel #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();
        }
Beispiel #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>
        /// <param name="onlyInspect">无关紧要的参数(用于检查器,外部不可用)</param>
        public static void Do(Func <double> intervalHandler, Func <SpareTimer, long, Task> doWhat = default, string workerName = default, string description = default, bool startNow = true, bool cancelInNoneNextTime = true, SpareTimeExecuteTypes executeType = SpareTimeExecuteTypes.Parallel, bool continued = true, bool onlyInspect = false)
        {
            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
            };

            // 支持异步事件
            async Task handler(object sender, ElapsedEventArgs e)
            {
                // 获取当前任务的记录
                _ = WorkerRecords.TryGetValue(workerName, out var currentRecord);

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

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

                // 记录执行次数
                if (timer.Type == SpareTimeTypes.Interval)
                {
                    currentRecord.Timer.Tally = timer.Tally = currentRecord.Tally += 1;
                }

                // 处理多线程并发问题(重入问题)
                var interlocked = currentRecord.Interlocked;

                if (Interlocked.Exchange(ref interlocked, 1) == 0)
                {
                    try
                    {
                        // 执行前通知
                        if (timer.Type == SpareTimeTypes.Interval && !onlyInspect)
                        {
                            await WriteChannel(timer, 1);
                        }

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

                        // 只要执行成功一次,那么清空异常信息
                        currentRecord.Timer.Exception.Clear();

                        // 执行成功通知
                        if (timer.Type == SpareTimeTypes.Interval && !onlyInspect)
                        {
                            await WriteChannel(timer, 2);
                        }
                    }
                    catch (Exception ex)
                    {
                        // 执行异常通知
                        if (timer.Type == SpareTimeTypes.Interval && !onlyInspect)
                        {
                            await WriteChannel(timer, 3);
                        }

                        // 记录任务异常
                        currentRecord.Timer.Exception.TryAdd(currentRecord.Tally, ex);

                        // 如果任务执行超过 10 次失败,则停止任务
                        if (currentRecord.Timer.Exception.Count > 10)
                        {
                            Stop(workerName, true);
                        }
                    }
                    finally
                    {
                        // 释放未托管对象
                        App.DisposeUnmanagedObjects();

                        // 处理串行执行问题
                        currentRecord.IsCompleteOfPrev = true;

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

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

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

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

            // 订阅执行事件
            timer.Elapsed += (sender, e) => handler(sender, e).GetAwaiter().GetResult();

            timer.AutoReset = continued;
            if (startNow)
            {
                Start(timer.WorkerName);
            }
        }
Beispiel #3
0
 /// <summary>
 /// 构造函数
 /// </summary>
 /// <param name="timer"></param>
 /// <param name="status"></param>
 public SpareTimerExecuter(SpareTimer timer, int status)
 {
     Timer  = timer;
     Status = status;
 }
Beispiel #4
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();
            }
        }
Beispiel #5
0
 /// <summary>
 /// 写入管道消息
 /// </summary>
 /// <param name="timer"></param>
 /// <param name="statues"></param>
 /// <returns></returns>
 private static async Task WriteChannel(SpareTimer timer, int statues)
 {
     await ChannelContext <SpareTimerExecuter, SpareTimeListenerChannelHandler> .BoundedChannel.Writer.WriteAsync(new SpareTimerExecuter(timer, statues));
 }