CSharp: Iterator Pattern
项目结构:

/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:行为模式 Behavioral Patterns 迭代器模式 Iterator Pattern演示业务层
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/25 20:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : JewelleryProcessAggregate.cs
*/
using IteratorPattern.Core.Enums;
using IteratorPattern.Core.Iterator;
using IteratorPattern.Entities;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Text;
namespace IteratorPattern.Aggregates
{
/// <summary>
/// 珠宝业务工序聚合容器(线程安全)
/// IAggregate 实现,负责维护全部工序数据源
/// 对外提供多种迭代器创建入口:正向、反向、过滤迭代器
/// </summary>
public class JewelleryProcessAggregate : IAggregate<BusinessProcessNode>
{
/// <summary>
/// 读写锁:保障高并发场景下集合读写线程安全
/// </summary>
private readonly ReaderWriterLockSlim _rwLock = new ReaderWriterLockSlim();
/// <summary>
/// 内部工序存储列表
/// </summary>
private readonly List<BusinessProcessNode> _processNodes;
/// <summary>
/// 日志对象
/// </summary>
private readonly ILogger<JewelleryProcessAggregate> _logger;
/// <summary>
/// 构造注入日志,初始化全部业务工序
/// </summary>
/// <param name="logger">日志实例</param>
public JewelleryProcessAggregate(ILogger<JewelleryProcessAggregate> logger)
{
_logger = logger;
_processNodes = new List<BusinessProcessNode>();
InitializeAllProcessNodes();
}
/// <summary>
/// 初始化所有工序节点,划分链路类型
/// </summary>
private void InitializeAllProcessNodes()
{
_logger.LogDebug("开始加载珠宝全业务工序定义");
// ========== 生产链路 ProductionLink ==========
_processNodes.Add(new BusinessProcessNode
{
ProcessId = 1,
SortOrder = 1,
ProcessName = "原料采购核验",
LinkType = BusinessLinkType.ProductionLink,
ExecuteAsync = async () =>
{
await Task.Delay(10);
_logger.LogInformation("【原料采购核验】贵金属、宝石入库检验,凭证归档");
}
});
_processNodes.Add(new BusinessProcessNode
{
ProcessId = 2,
SortOrder = 2,
ProcessName = "设计制图",
LinkType = BusinessLinkType.ProductionLink,
ExecuteAsync = async () =>
{
await Task.Delay(10);
_logger.LogInformation("【设计制图】三维建模、首饰图纸确认");
}
});
_processNodes.Add(new BusinessProcessNode
{
ProcessId = 3,
SortOrder = 3,
ProcessName = "加工生产",
LinkType = BusinessLinkType.ProductionLink,
ExecuteAsync = async () =>
{
await Task.Delay(10);
_logger.LogInformation("【加工生产】起版、倒模、执模、镶石、抛光");
}
});
_processNodes.Add(new BusinessProcessNode
{
ProcessId = 4,
SortOrder = 4,
ProcessName = "质检",
LinkType = BusinessLinkType.ProductionLink,
ExecuteAsync = async () =>
{
await Task.Delay(10);
_logger.LogInformation("【质检】成色检测、瑕疵检验、证书出具");
}
});
_processNodes.Add(new BusinessProcessNode
{
ProcessId = 5,
SortOrder = 5,
ProcessName = "包装",
LinkType = BusinessLinkType.ProductionLink,
ExecuteAsync = async () =>
{
await Task.Delay(10);
_logger.LogInformation("【包装】首饰封装、礼盒打包、防盗标签");
}
});
_processNodes.Add(new BusinessProcessNode
{
ProcessId = 6,
SortOrder = 6,
ProcessName = "物流",
LinkType = BusinessLinkType.ProductionLink,
ExecuteAsync = async () =>
{
await Task.Delay(10);
_logger.LogInformation("【物流】货品出库、保价托运、轨迹跟踪");
}
});
// ========== 职能部门链路 DepartmentLink ==========
_processNodes.Add(new BusinessProcessNode
{
ProcessId = 7,
SortOrder = 7,
ProcessName = "财务",
LinkType = BusinessLinkType.DepartmentLink,
ExecuteAsync = async () =>
{
await Task.Delay(10);
_logger.LogInformation("【财务】成本核算、应收应付、资金对账");
}
});
_processNodes.Add(new BusinessProcessNode
{
ProcessId = 8,
SortOrder = 8,
ProcessName = "营销推广",
LinkType = BusinessLinkType.DepartmentLink,
ExecuteAsync = async () =>
{
await Task.Delay(10);
_logger.LogInformation("【营销推广】活动策划、新品宣传投放");
}
});
_processNodes.Add(new BusinessProcessNode
{
ProcessId = 9,
SortOrder = 9,
ProcessName = "业务",
LinkType = BusinessLinkType.DepartmentLink,
ExecuteAsync = async () =>
{
await Task.Delay(10);
_logger.LogInformation("【业务】客户洽谈、订单跟进、售后维护");
}
});
_processNodes.Add(new BusinessProcessNode
{
ProcessId = 10,
SortOrder = 10,
ProcessName = "人事行政",
LinkType = BusinessLinkType.DepartmentLink,
ExecuteAsync = async () =>
{
await Task.Delay(10);
_logger.LogInformation("【人事行政】招聘、考勤、行政物资管理");
}
});
_processNodes.Add(new BusinessProcessNode
{
ProcessId = 11,
SortOrder = 11,
ProcessName = "IT",
LinkType = BusinessLinkType.DepartmentLink,
ExecuteAsync = async () =>
{
await Task.Delay(10);
_logger.LogInformation("【IT】系统运维、软硬件故障处理");
}
});
_processNodes.Add(new BusinessProcessNode
{
ProcessId = 12,
SortOrder = 12,
ProcessName = "培训",
LinkType = BusinessLinkType.DepartmentLink,
ExecuteAsync = async () =>
{
await Task.Delay(10);
_logger.LogInformation("【培训】珠宝工艺、销售专业培训");
}
});
_logger.LogInformation("工序初始化完成,总工序数量:{Count}", _processNodes.Count);
}
/// <summary>
/// IAggregate 标准接口:创建基础正向迭代器
/// </summary>
public IIterator<BusinessProcessNode> CreateIterator()
{
_rwLock.EnterReadLock();
try
{
var snapshot = _processNodes.ToList().AsReadOnly();
return new JewelleryProcessIterator(snapshot);
}
finally
{
_rwLock.ExitReadLock();
}
}
/// <summary>
/// 创建反向迭代器
/// </summary>
/// <returns>反向遍历迭代器</returns>
public IProcessIterator CreateReverseIterator()
{
_rwLock.EnterReadLock();
try
{
var snapshot = _processNodes.ToList().AsReadOnly();
return new ReverseProcessIterator(snapshot);
}
finally
{
_rwLock.ExitReadLock();
}
}
/// <summary>
/// 创建过滤迭代器(按业务链路筛选)
/// </summary>
/// <param name="linkType">链路类型</param>
/// <returns>过滤后的迭代器</returns>
public IProcessIterator CreateFilterIterator(BusinessLinkType linkType)
{
_rwLock.EnterReadLock();
try
{
var snapshot = _processNodes.ToList();
return new FilterProcessIterator(snapshot, linkType);
}
finally
{
_rwLock.ExitReadLock();
}
}
/// <summary>
/// 释放读写锁资源
/// </summary>
public void Dispose()
{
_rwLock?.Dispose();
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:行为模式 Behavioral Patterns 迭代器模式 Iterator Pattern演示业务层
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/25 20:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : BusinessLinkType.cs
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace IteratorPattern.Core.Enums
{
/// <summary>
/// 业务链路类型枚举
/// 用于过滤迭代器筛选不同业务流程
/// </summary>
public enum BusinessLinkType
{
/// <summary>
/// 未指定
/// </summary>
None,
/// <summary>
/// 生产主链路:原料、设计、加工、质检、包装、物流
/// </summary>
ProductionLink,
/// <summary>
/// 职能部门链路:财务、营销、人事、IT、培训等
/// </summary>
DepartmentLink
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:行为模式 Behavioral Patterns 迭代器模式 Iterator Pattern演示业务层
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/25 20:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : FilterProcessIterator.cs
*/
using IteratorPattern.Core.Enums;
using IteratorPattern.Entities;
using System;
using System.Collections.Generic;
using System.Text;
namespace IteratorPattern.Core.Iterator
{
/// <summary>
/// 过滤条件迭代器
/// 根据 BusinessLinkType 筛选【生产链路 / 职能部门链路】
/// 对外保持迭代器统一接口,上层调度器无需修改代码
/// </summary>
public class FilterProcessIterator : IProcessIterator
{
/// <summary>
/// 过滤后得到的工序子集
/// </summary>
private readonly IReadOnlyList<BusinessProcessNode> _filteredNodes;
/// <summary>
/// 当前索引
/// </summary>
private int _currentIndex;
/// <summary>
/// 构造函数:按链路类型自动过滤工序
/// </summary>
/// <param name="sourceNodes">全部原始工序集合</param>
/// <param name="linkType">需要筛选的链路类型</param>
public FilterProcessIterator(IEnumerable<BusinessProcessNode> sourceNodes, BusinessLinkType linkType)
{
if (sourceNodes == null)
throw new ArgumentNullException(nameof(sourceNodes));
_filteredNodes = sourceNodes
.Where(x => x.LinkType == linkType)
.OrderBy(x => x.SortOrder)
.ToList()
.AsReadOnly();
_currentIndex = 0;
}
public bool HasNext()
{
return _currentIndex < _filteredNodes.Count;
}
public BusinessProcessNode Next()
{
if (!HasNext())
{
throw new InvalidOperationException("过滤迭代器已遍历完毕");
}
var node = _filteredNodes[_currentIndex];
_currentIndex++;
return node;
}
public void Reset()
{
_currentIndex = 0;
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:行为模式 Behavioral Patterns 迭代器模式 Iterator Pattern演示业务层
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/25 20:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : IAggregate.cs
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace IteratorPattern.Core.Iterator
{
/// <summary>
/// 聚合集合抽象接口
/// Iterator Pattern:提供创建迭代器的入口
/// </summary>
/// <typeparam name="T">集合内元素类型</typeparam>
public interface IAggregate<T>
{
/// <summary>
/// 创建标准正向迭代器
/// </summary>
/// <returns>迭代器实例</returns>
IIterator<T> CreateIterator();
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:行为模式 Behavioral Patterns 迭代器模式 Iterator Pattern演示业务层
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/25 20:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : IIterator.cs
*/
using IteratorPattern.Entities;
using System;
using System.Collections.Generic;
using System.Text;
namespace IteratorPattern.Core.Iterator
{
/// <summary>
/// 异步迭代器通用接口
/// Iterator Pattern 抽象迭代器
/// </summary>
/// <typeparam name="T">遍历元素类型</typeparam>
public interface IIterator<T>
{
/// <summary>
/// 判断是否存在下一个元素
/// </summary>
/// <returns>true:存在下一项;false:遍历结束</returns>
bool HasNext();
/// <summary>
/// 获取下一个元素
/// </summary>
/// <returns>目标实体对象</returns>
T Next();
/// <summary>
/// 重置迭代指针至起始位置
/// </summary>
void Reset();
}
/// <summary>
/// 业务工序专用迭代器别名,简化调用
/// </summary>
public interface IProcessIterator : IIterator<BusinessProcessNode>
{
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:行为模式 Behavioral Patterns 迭代器模式 Iterator Pattern演示业务层
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/25 20:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : JewelleryProcessIterator.cs
*/
using IteratorPattern.Entities;
using System;
using System.Collections.Generic;
using System.Text;
namespace IteratorPattern.Core.Iterator
{
/// <summary>
/// 基础正向工序迭代器
/// 从头到尾顺序遍历全部工序节点
/// 多线程并发遍历只读安全
/// </summary>
public class JewelleryProcessIterator : IProcessIterator
{
/// <summary>
/// 原始只读工序集合
/// </summary>
private readonly IReadOnlyList<BusinessProcessNode> _sourceNodes;
/// <summary>
/// 当前遍历索引
/// </summary>
private int _currentIndex;
/// <summary>
/// 构造函数注入只读工序集合
/// </summary>
/// <param name="sourceNodes">工序只读列表</param>
public JewelleryProcessIterator(IReadOnlyList<BusinessProcessNode> sourceNodes)
{
_sourceNodes = sourceNodes ?? throw new ArgumentNullException(nameof(sourceNodes));
_currentIndex = 0;
}
/// <summary>
/// 判断是否存在下一个工序
/// </summary>
public bool HasNext()
{
return _currentIndex < _sourceNodes.Count;
}
/// <summary>
/// 获取下一个工序节点
/// </summary>
public BusinessProcessNode Next()
{
if (!HasNext())
{
throw new InvalidOperationException("迭代器已到达集合末尾,无更多元素");
}
var item = _sourceNodes[_currentIndex];
_currentIndex++;
return item;
}
/// <summary>
/// 重置索引指针回到起点
/// </summary>
public void Reset()
{
_currentIndex = 0;
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:行为模式 Behavioral Patterns 迭代器模式 Iterator Pattern演示业务层
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/25 20:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : ReverseProcessIterator.cs
*/
using IteratorPattern.Entities;
using System;
using System.Collections.Generic;
using System.Text;
namespace IteratorPattern.Core.Iterator
{
/// <summary>
/// 反向工序迭代器
/// 从最后一项向前倒序遍历
/// </summary>
public class ReverseProcessIterator : IProcessIterator
{
/// <summary>
/// 原始只读工序集合
/// </summary>
private readonly IReadOnlyList<BusinessProcessNode> _sourceNodes;
/// <summary>
/// 当前遍历索引
/// </summary>
private int _currentIndex;
/// <summary>
/// 构造反向迭代器
/// </summary>
/// <param name="sourceNodes">工序只读集合</param>
public ReverseProcessIterator(IReadOnlyList<BusinessProcessNode> sourceNodes)
{
_sourceNodes = sourceNodes ?? throw new ArgumentNullException(nameof(sourceNodes));
_currentIndex = sourceNodes.Count - 1;
}
public bool HasNext()
{
return _currentIndex >= 0;
}
public BusinessProcessNode Next()
{
if (!HasNext())
{
throw new InvalidOperationException("反向迭代器遍历完成,不存在下一项");
}
var node = _sourceNodes[_currentIndex];
_currentIndex--;
return node;
}
public void Reset()
{
_currentIndex = _sourceNodes.Count - 1;
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:行为模式 Behavioral Patterns 迭代器模式 Iterator Pattern演示业务层
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/25 20:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : BusinessProcessNode.cs
*/
using IteratorPattern.Core.Enums;
using System;
using System.Collections.Generic;
using System.Text;
namespace IteratorPattern.Entities
{
/// <summary>
/// 珠宝业务工序节点实体
/// 存储工序基础信息与异步执行委托
/// </summary>
public class BusinessProcessNode
{
/// <summary>
/// 工序唯一ID
/// </summary>
public int ProcessId { get; set; }
/// <summary>
/// 工序名称
/// </summary>
public string ProcessName { get; set; } = string.Empty;
/// <summary>
/// 全局执行顺序号
/// </summary>
public int SortOrder { get; set; }
/// <summary>
/// 当前工序归属链路类型
/// </summary>
public BusinessLinkType LinkType { get; set; }
/// <summary>
/// 异步工序执行逻辑委托
/// </summary>
public Func<Task> ExecuteAsync { get; set; } = async () => await Task.CompletedTask;
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:行为模式 Behavioral Patterns 迭代器模式 Iterator Pattern演示业务层
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/25 20:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : LogConfigSwitch.cs
*/
using Karambolo.Extensions.Logging.File;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.IO;
namespace IteratorPattern.Infrastructure.Logging
{
/// <summary>
/// 日志配置切换工具
/// 模式1:普通文本日志(原有格式,控制台与文件保持一致)
/// 模式2:Json结构化日志(用于日志收集平台)
/// </summary>
public static class LogConfigSwitch
{
/// <summary>
/// 是否启用Json结构化日志
/// true=Json格式;false=普通文本模板
/// 修改此处一键切换
/// </summary>
public const bool EnableJsonStructuredLog = false;
/// <summary>
/// 配置文件日志(使用 Karambolo 4.x API)
/// </summary>
public static void ConfigureFileLogger(ILoggingBuilder loggingBuilder)
{
string todayDate = DateTime.Now.ToString("yyyy-MM-dd");
string logRootPath = Path.Combine(Directory.GetCurrentDirectory(), "Logs");
loggingBuilder.AddFile(fileBuilder =>
{
fileBuilder.RootPath = logRootPath;
fileBuilder.Files = new[]
{
new LogFileOptions
{
Path = $"{todayDate}/app-debug.log",
MinLevel = new Dictionary<string, LogLevel> { [""] = LogLevel.Debug },
MaxFileSize = 100 * 1024 * 1024
},
new LogFileOptions
{
Path = $"{todayDate}/app-info.log",
MinLevel = new Dictionary<string, LogLevel> { [""] = LogLevel.Information },
MaxFileSize = 100 * 1024 * 1024
},
new LogFileOptions
{
Path = $"{todayDate}/app-warn.log",
MinLevel = new Dictionary<string, LogLevel> { [""] = LogLevel.Warning },
MaxFileSize = 100 * 1024 * 1024
},
new LogFileOptions
{
Path = $"{todayDate}/app-error.log",
MinLevel = new Dictionary<string, LogLevel> { [""] = LogLevel.Error },
MaxFileSize = 100 * 1024 * 1024
}
};
});
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:行为模式 Behavioral Patterns 迭代器模式 Iterator Pattern演示业务层
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/25 20:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : RetryHelper.cs
*/
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Text;
namespace IteratorPattern.Infrastructure.Resilience
{
/// <summary>
/// 通用异步重试帮助类
/// 用于珠宝业务工序、定时任务异常自动重试
/// </summary>
public class RetryHelper
{
/// <summary>
/// 日志对象
/// </summary>
private readonly ILogger<RetryHelper> _logger;
/// <summary>
/// 构造注入日志
/// </summary>
/// <param name="logger">日志实例</param>
public RetryHelper(ILogger<RetryHelper> logger)
{
_logger = logger;
}
/// <summary>
/// 执行异步任务,失败自动重试
/// </summary>
/// <param name="action">待执行异步业务方法</param>
/// <param name="maxRetryTimes">最大重试次数</param>
/// <param name="delayMs">每次重试间隔(毫秒)</param>
/// <param name="cancellationToken">取消令牌</param>
/// <param name="skipExceptions">不需要重试的异常类型集合</param>
/// <returns>是否最终执行成功</returns>
public async Task<bool> ExecuteWithRetryAsync(
Func<Task> action,
int maxRetryTimes = 3,
int delayMs = 2000,
CancellationToken cancellationToken = default,
HashSet<Type>? skipExceptions = null)
{
if (action == null)
throw new ArgumentNullException(nameof(action));
int currentRetry = 0;
while (true)
{
try
{
await action.Invoke();
if (currentRetry > 0)
{
_logger.LogInformation("业务执行成功!经过{RetryTimes}次重试", currentRetry);
}
return true;
}
catch (Exception ex)
{
// 如果属于跳过异常,直接抛出不重试
if (skipExceptions != null && skipExceptions.Contains(ex.GetType()))
{
_logger.LogError(ex, "捕获到无需重试的异常,终止执行");
throw;
}
currentRetry++;
if (currentRetry > maxRetryTimes)
{
_logger.LogError(ex, "已达到最大重试次数{MaxRetry},任务执行失败", maxRetryTimes);
return false;
}
_logger.LogWarning(ex, "业务执行异常,准备第{CurrentRetry}/{MaxRetry}次重试,等待{Delay}ms",
currentRetry, maxRetryTimes, delayMs);
await Task.Delay(delayMs, cancellationToken);
}
}
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:行为模式 Behavioral Patterns 迭代器模式 Iterator Pattern演示业务层
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/25 20:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : JewelleryProcessJob.cs
*/
using IteratorPattern.Core.Enums;
using IteratorPattern.Infrastructure.Resilience;
using IteratorPattern.Schedulers;
using Microsoft.Extensions.Logging;
using Quartz;
using System;
using System.Collections.Generic;
namespace IteratorPattern.Infrastructure.Tasks
{
/// <summary>
/// Quartz定时任务:珠宝业务流程执行Job
/// 支持配置执行链路:全流程/生产链路/职能部门链路
/// 内置异常重试策略
/// </summary>
[DisallowConcurrentExecution] // 禁止同一个任务并发执行,防止业务重复跑
public class JewelleryProcessJob : IJob
{
/// <summary>
/// 业务流程调度器
/// </summary>
private readonly BusinessProcessScheduler _processScheduler;
/// <summary>
/// 重试工具类
/// </summary>
private readonly RetryHelper _retryHelper;
/// <summary>
/// 日志
/// </summary>
private readonly ILogger<JewelleryProcessJob> _logger;
/// <summary>
/// DI构造注入依赖
/// </summary>
public JewelleryProcessJob(
BusinessProcessScheduler processScheduler,
RetryHelper retryHelper,
ILogger<JewelleryProcessJob> logger)
{
_processScheduler = processScheduler;
_retryHelper = retryHelper;
_logger = logger;
}
/// <summary>
/// Quartz任务执行入口
/// </summary>
/// <param name="context">任务执行上下文</param>
public async Task Execute(IJobExecutionContext context)
{
try
{
_logger.LogInformation("Quartz定时任务启动,任务Key:{JobKey}", context.JobDetail.Key);
// 从JobDataMap读取配置参数,灵活指定执行链路
var linkTypeStr = context.MergedJobDataMap.GetString("TargetLinkType");
Enum.TryParse(linkTypeStr, out BusinessLinkType targetLink);
bool executeResult;
if (targetLink == BusinessLinkType.None)
{
// 执行全部工序链路
executeResult = await _retryHelper.ExecuteWithRetryAsync(
() => _processScheduler.RunFullAllProcessAsync(context.CancellationToken),
maxRetryTimes: 3,
delayMs: 3000,
cancellationToken: context.CancellationToken);
}
else
{
// 执行指定过滤链路(生产/职能部门)
executeResult = await _retryHelper.ExecuteWithRetryAsync(
() => _processScheduler.RunFilterLinkAsync(targetLink, context.CancellationToken),
maxRetryTimes: 3,
delayMs: 3000,
cancellationToken: context.CancellationToken);
}
if (!executeResult)
{
// 多次重试仍然失败,可以扩展:短信/邮件告警
_logger.LogCritical("定时业务任务最终执行失败,请人工核查!");
}
else
{
_logger.LogInformation("Quartz定时任务正常执行完成,任务Key:{JobKey}", context.JobDetail.Key);
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Quartz Job 顶层捕获未处理异常,任务中断");
}
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:行为模式 Behavioral Patterns 迭代器模式 Iterator Pattern演示业务层
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/25 20:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : BusinessProcessScheduler.cs
*/
using IteratorPattern.Aggregates;
using IteratorPattern.Core.Enums;
using IteratorPattern.Core.Iterator;
using IteratorPattern.Entities;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Text;
namespace IteratorPattern.Schedulers
{
/// <summary>
/// 珠宝业务流程异步调度器
/// 使用各类迭代器驱动不同业务链路执行
/// 全部逻辑异步实现,支持取消令牌
/// </summary>
public class BusinessProcessScheduler
{
/// <summary>
/// 日志实例
/// </summary>
private readonly ILogger<BusinessProcessScheduler> _logger;
/// <summary>
/// 工序聚合数据源
/// </summary>
private readonly JewelleryProcessAggregate _processAggregate;
/// <summary>
/// DI构造注入依赖
/// </summary>
/// <param name="logger">日志</param>
/// <param name="aggregate">工序聚合容器</param>
public BusinessProcessScheduler(ILogger<BusinessProcessScheduler> logger, JewelleryProcessAggregate aggregate)
{
_logger = logger;
_processAggregate = aggregate;
}
/// <summary>
/// 执行全链路正向遍历(所有工序)
/// </summary>
/// <param name="cancellationToken">取消令牌</param>
public async Task RunFullAllProcessAsync(CancellationToken cancellationToken = default)
{
try
{
_logger.LogInformation("==========【开始执行全部业务工序正向流程】==========");
IProcessIterator iterator = (IProcessIterator)_processAggregate.CreateIterator();
while (iterator.HasNext() && !cancellationToken.IsCancellationRequested)
{
BusinessProcessNode node = iterator.Next();
_logger.LogDebug("开始执行工序:{ProcessName} | 链路:{LinkType}", node.ProcessName, node.LinkType);
await node.ExecuteAsync();
}
_logger.LogInformation("==========【全部业务工序正向流程执行完毕】==========");
}
catch (Exception ex)
{
_logger.LogError(ex, "执行全业务流程发生异常");
}
}
/// <summary>
/// 执行指定链路过滤流程
/// </summary>
/// <param name="linkType">链路类型</param>
/// <param name="cancellationToken">取消令牌</param>
public async Task RunFilterLinkAsync(BusinessLinkType linkType, CancellationToken cancellationToken = default)
{
try
{
string linkName = linkType == BusinessLinkType.ProductionLink ? "生产主链路" : "职能部门链路";
_logger.LogInformation($"==========【开始执行{linkName}】==========");
IProcessIterator iterator = _processAggregate.CreateFilterIterator(linkType);
if (!iterator.HasNext())
{
_logger.LogWarning("{LinkName}未匹配到任何工序", linkName);
return;
}
while (iterator.HasNext() && !cancellationToken.IsCancellationRequested)
{
BusinessProcessNode node = iterator.Next();
_logger.LogDebug("执行工序:{ProcessName}", node.ProcessName);
await node.ExecuteAsync();
}
_logger.LogInformation($"==========【{linkName}执行完成】==========");
}
catch (Exception ex)
{
_logger.LogError(ex, "过滤链路执行异常,链路类型:{LinkType}", linkType);
}
}
/// <summary>
/// 反向遍历所有工序(演示反向迭代器)
/// </summary>
/// <param name="cancellationToken">取消令牌</param>
public async Task RunReverseAllProcessAsync(CancellationToken cancellationToken = default)
{
try
{
_logger.LogWarning("==========【启动工序反向遍历流程(测试)】==========");
IProcessIterator iterator = _processAggregate.CreateReverseIterator();
while (iterator.HasNext() && !cancellationToken.IsCancellationRequested)
{
BusinessProcessNode node = iterator.Next();
_logger.LogDebug("反向遍历工序:{ProcessName}", node.ProcessName);
await node.ExecuteAsync();
}
_logger.LogInformation("==========【工序反向遍历流程结束】==========");
}
catch (Exception ex)
{
_logger.LogError(ex, "反向遍历流程异常");
}
}
}
}
调用:
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:行为模式 Behavioral Patterns 迭代器模式 Iterator Pattern演示业务层
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/07/25 20:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : IteratorBll.cs
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using IteratorPattern.Aggregates;
using IteratorPattern.Core.Enums;
using IteratorPattern.Infrastructure.Logging;
using IteratorPattern.Infrastructure.Resilience;
using IteratorPattern.Infrastructure.Tasks;
using IteratorPattern.Schedulers;
using Karambolo.Extensions.Logging.File;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Quartz;
namespace BLL
{
/// <summary>
/// 迭代器模式业务演示
/// </summary>
public class IteratorBll
{
/// <summary>
/// 演示迭代器模式
/// </summary>
public async Task Demo()
{
Console.WriteLine("=====迭代器模式演示启动=====\n");
#region 第一部分:基础演示
Console.WriteLine("【第一部分】基础演示 - 全工序执行");
Console.WriteLine("----------------------------------------");
var host = Host.CreateDefaultBuilder(Array.Empty<string>())
.ConfigureLogging((ctx, loggingBuilder) =>
{
loggingBuilder.ClearProviders();
loggingBuilder.AddConsole();
// 文件日志配置 Karambolo 4.x
string todayDate = DateTime.Now.ToString("yyyy-MM-dd");
string logRootPath = Path.Combine(Directory.GetCurrentDirectory(), "Logs");
loggingBuilder.AddFile(fileBuilder =>
{
fileBuilder.RootPath = logRootPath;
fileBuilder.Files = new[]
{
new LogFileOptions { Path = $"{todayDate}/app-debug.log", MinLevel = new Dictionary<string, LogLevel> { [""] = LogLevel.Debug }, MaxFileSize = 100 * 1024 * 1024 },
new LogFileOptions { Path = $"{todayDate}/app-info.log", MinLevel = new Dictionary<string, LogLevel> { [""] = LogLevel.Information }, MaxFileSize = 100 * 1024 * 1024 },
new LogFileOptions { Path = $"{todayDate}/app-warn.log", MinLevel = new Dictionary<string, LogLevel> { [""] = LogLevel.Warning }, MaxFileSize = 100 * 1024 * 1024 },
new LogFileOptions { Path = $"{todayDate}/app-error.log", MinLevel = new Dictionary<string, LogLevel> { [""] = LogLevel.Error }, MaxFileSize = 100 * 1024 * 1024 }
};
});
loggingBuilder.SetMinimumLevel(LogLevel.Debug);
})
.ConfigureServices((ctx, services) =>
{
services.AddScoped<JewelleryProcessAggregate>();
services.AddScoped<BusinessProcessScheduler>();
})
.Build();
using (var scope = host.Services.CreateScope())
{
var scheduler = scope.ServiceProvider.GetRequiredService<BusinessProcessScheduler>();
var logger = scope.ServiceProvider.GetRequiredService<ILogger<IteratorBll>>();
logger.LogInformation("开始执行全工序正向流程");
Console.WriteLine("1. 完整全工序正向执行:");
await scheduler.RunFullAllProcessAsync();
Console.WriteLine();
logger.LogInformation("开始执行生产链路过滤");
Console.WriteLine("2. 单独执行【生产链路】:");
await scheduler.RunFilterLinkAsync(BusinessLinkType.ProductionLink);
Console.WriteLine();
logger.LogInformation("开始执行职能部门链路过滤");
Console.WriteLine("3. 单独执行【职能部门链路】:");
await scheduler.RunFilterLinkAsync(BusinessLinkType.DepartmentLink);
Console.WriteLine();
logger.LogInformation("开始执行反向遍历");
Console.WriteLine("4. 反向遍历测试:");
await scheduler.RunReverseAllProcessAsync();
}
await host.StopAsync();
host.Dispose();
Console.WriteLine("第一部分执行完成\n");
#endregion
#region 第二部分:Quartz定时任务演示
Console.WriteLine("【第二部分】Quartz定时任务演示");
Console.WriteLine("----------------------------------------");
var host2 = Host.CreateDefaultBuilder(Array.Empty<string>())
.ConfigureLogging((ctx, loggingBuilder) =>
{
loggingBuilder.ClearProviders();
loggingBuilder.AddConsole();
// 使用统一日志配置
LogConfigSwitch.ConfigureFileLogger(loggingBuilder);
loggingBuilder.SetMinimumLevel(LogLevel.Debug);
})
.ConfigureServices((ctx, services) =>
{
services.AddScoped<JewelleryProcessAggregate>();
services.AddScoped<BusinessProcessScheduler>();
services.AddScoped<RetryHelper>();
// ========== Quartz 定时任务注册 ==========
services.AddQuartz(q =>
{
q.AddJob<JewelleryProcessJob>(opts => opts.WithIdentity("JewelleryProcessJob"));
// 触发器1:每天凌晨02:00 执行【完整全业务链路】
q.AddTrigger(opts => opts
.ForJob("JewelleryProcessJob")
.WithIdentity("Trigger_FullProcess")
.WithCronSchedule("0 0 2 * * ?")
.UsingJobData("TargetLinkType", nameof(BusinessLinkType.None)));
// 触发器2:每天上午09:30 执行【生产链路】
q.AddTrigger(opts => opts
.ForJob("JewelleryProcessJob")
.WithIdentity("Trigger_ProductionLink")
.WithCronSchedule("0 30 9 * * ?")
.UsingJobData("TargetLinkType", nameof(BusinessLinkType.ProductionLink)));
// 触发器3:每周一 10:00 执行【职能部门链路】
q.AddTrigger(opts => opts
.ForJob("JewelleryProcessJob")
.WithIdentity("Trigger_DepartmentLink")
.WithCronSchedule("0 0 10 ? * MON")
.UsingJobData("TargetLinkType", nameof(BusinessLinkType.DepartmentLink)));
});
services.AddQuartzHostedService(opt =>
{
opt.WaitForJobsToComplete = false;
});
})
.Build();
// 演示同步手动执行
using (var scope2 = host2.Services.CreateScope())
{
var scheduler = scope2.ServiceProvider.GetRequiredService<BusinessProcessScheduler>();
var logger = scope2.ServiceProvider.GetRequiredService<ILogger<IteratorBll>>();
logger.LogInformation("手动执行全工序流程");
Console.WriteLine("手动执行全工序流程:");
await scheduler.RunFullAllProcessAsync();
Console.WriteLine();
logger.LogInformation("手动执行生产链路");
Console.WriteLine("手动执行生产链路:");
await scheduler.RunFilterLinkAsync(BusinessLinkType.ProductionLink);
}
Console.WriteLine();
Console.WriteLine("==============================");
Console.WriteLine("程序启动完成,Quartz定时调度器已运行");
Console.WriteLine("按任意键退出程序");
Console.WriteLine("==============================");
Console.ReadKey();
await host2.StopAsync();
#endregion
}
}
}
输出:

哲学管理(学)人生, 文学艺术生活, 自动(计算机学)物理(学)工作, 生物(学)化学逆境, 历史(学)测绘(学)时间, 经济(学)数学金钱(理财), 心理(学)医学情绪, 诗词美容情感, 美学建筑(学)家园, 解构建构(分析)整合学习, 智商情商(IQ、EQ)运筹(学)生存.---Geovin Du(涂聚文)
浙公网安备 33010602011771号