diff --git "a/Doc/_\346\226\207\346\241\243\351\207\215\345\273\272\350\277\233\345\272\246.md" "b/Doc/_\346\226\207\346\241\243\351\207\215\345\273\272\350\277\233\345\272\246.md"
new file mode 100644
index 0000000..f87fb0b
--- /dev/null
+++ "b/Doc/_\346\226\207\346\241\243\351\207\215\345\273\272\350\277\233\345\272\246.md"
@@ -0,0 +1,143 @@
+# NewLife.Core �ĵ��ؽ�����
+
+## ����
+
+��������Ŀ�����ؽ� NewLife.Core ���������ʹ���ֲᣬ���ڣ�
+- �����ĵ�����ҳ��https://newlifex.com/core/nav
+- ���Դ�����
+- ����DocĿ¼�ĵ�����
+
+## �ĵ������淶
+
+�ļ���ʽ��`{Ӣ����}-{���ı���}.md`
+
+ʾ����
+- `tracer-��·��ITracer.md`
+- `cron-Cron����ʽ.md`
+- `timerx-����ʱ��TimerX.md`
+
+## ������ĵ�
+
+### ʵ�������4/18��
+
+- [x] tracer-��·��ITracer.md
+- [x] cron-Cron����ʽ.md
+- [x] timerx-����ʱ��TimerX.md
+- [x] log-��־ILog.md
+- [ ] machine_info-������ϢMachineInfo.md
+- [ ] pinyin-ƴ����PinYin.md
+- [ ] object_container-��������ObjectContainer.md
+- [ ] host-������Ӧ������Host.md
+- [ ] plugin-������IPlugin.md
+- [ ] actor-�����Actor.md
+- [ ] script_engine-�ű�����ScriptEngine.md
+- [ ] compression-ѹ����ѹ��.md
+- [ ] weak_action-��������WeakAction.md
+- [ ] token_provider-�ֲ�ʽ����ǩ������TokenProvider.md
+- [ ] jwt-Webͨ������JwtBuilder.md
+- [ ] baidu_map-�ٶȵ�ͼ�ӿ�BaiduMap.md
+- [ ] amap-�ߵµ�ͼ�ӿ�AMap.md
+- [ ] oss-�����ƶ���洢OssClient.md
+
+### ������չ��0/9��
+
+- [ ] utility-����ת��Utility.md
+- [ ] string_helper-�ַ�����չStringHelper.md
+- [ ] process_helper-������չProcessHelper.md
+- [ ] path_helper-·����չPathHelper.md
+- [ ] io_helper-������չIOHelper.md
+- [ ] security_helper-��ȫ��չSecurityHelper.md
+- [ ] disposebase-������DisposeBase.md
+- [ ] reflect-������չReflect.md
+- [ ] runtime-����ʱ��ϢRuntime.md
+
+### ���л������ã�0/9��
+
+- [ ] json-Json���л�.md
+- [ ] xml-Xml���л�.md
+- [ ] binary-���������л�.md
+- [ ] csv_file-Csv����CsvFile.md
+- [ ] csv_db-Csv���ݿ�CsvDb.md
+- [ ] excel_reader-������Excel��ȡ��ExcelReader.md
+- [ ] config-����ϵͳIConfigProvider.md
+- [ ] setting-��������Setting.md
+- [ ] sysconfig-ϵͳ����SysConfig.md
+
+### ���ݻ��棨0/11��
+
+- [ ] icache-ͳһ����ӿ�ICache.md
+- [ ] icacheprovider-����ܹ�ICacheProvider.md
+- [ ] memory_cache-�ڴ滺��MemoryCache.md
+- [ ] dictionary_cache-�ֵ仺��DictionaryCache.md
+- [ ] object_pool-�����ObjectPool.md
+- [ ] packet-���ݰ�Packet.md
+- [ ] page_parameter-��ҳ����PageParameter.md
+- [ ] dbtable-���ݼ�DbTable.md
+- [ ] snow_flake-ѩ���㷨Snowflake.md
+- [ ] geo_hash-��γ�ȹ�ϣGeoHash.md
+
+### ����⣨0/10��
+
+- [ ] netserver-���������NetServer.md
+- [ ] socket_client-����ͻ���ISocketClient.md
+- [ ] api_http-ApiHttpClient�ͻ���.md
+- [ ] srmp-����Զ����Ϣ����Э��SRMP.md
+- [ ] packet_codec-���ݰ�������PacketCodec.md
+- [ ] api_server-RPCͨ��ApiServer.md
+- [ ] api_client-RPCͨ��ApiClient.md
+- [ ] webclient-��������WebClientX.md
+- [ ] httpserver-Web������HttpServer.md
+- [ ] websocket-WebSocket������.md
+
+### ʵս���飨0/3��
+
+- [ ] agent_service-֧�ֶ��ֲ���ϵͳ����һ����������.md
+- [ ] no_log-��ιر���־���.md
+- [ ] timerx_timeprovider-ʹ��TimeProvider�Ľ�Cron���Զ�ʱ����.md
+
+## ��ǰ����
+
+**�ܼ�**��4/60 (Լ7%)
+
+## ��һ���ƻ�
+
+�����������ģ����ĵ�������Ҫ������
+
+1. **������Ϣ MachineInfo** - Ӳ����Ϣ��ȡ
+2. **�������� ObjectContainer** - ����ע��
+3. **����� ObjectPool** - ������
+4. **����ϵͳ IConfigProvider** - ���ù���
+5. **Json���л�** - �������л�
+6. **��������� NetServer** - ������
+7. **ApiHttpClient** - Web API����
+8. **�ڴ滺�� MemoryCache** - ����ϵͳ
+
+## ִ�в���
+
+������������60ƪ�ĵ������������²��ԣ�
+
+1. **��������**��ÿ�δ���5-10ƪ�ĵ�
+2. **���ȼ�**������ɳ���ģ��
+3. **Դ������**������ʵ��Դ����д�ĵ�
+4. **����һ��**����ѭ�Ѵ����ĵ��ĸ�ʽ�ͷ��
+
+## �ĵ���
+
+ÿƪ�ĵ�������
+- ���������+���ԣ�
+- �������ţ����ʾ����
+- ����API���ӿ�/��/����˵����
+- ʹ�ó�����ʵ��Ӧ��ʾ����
+- ���ʵ�����Ƽ�������
+- ע������������壩
+- �������⣨FAQ��
+- �ο����ϣ�������ӣ�
+- ������־���汾��ʷ��
+
+## ����ʱ��
+
+�����£�2025-01-07
+
+---
+
+**ע��**�����ļ����ڸ����ĵ��ؽ����ȣ������������չ�������¡�
diff --git "a/Doc/Cron\350\241\250\350\276\276\345\274\217.md" "b/Doc/Cron\350\241\250\350\276\276\345\274\217.md"
new file mode 100644
index 0000000..eb96445
--- /dev/null
+++ "b/Doc/Cron\350\241\250\350\276\276\345\274\217.md"
@@ -0,0 +1,503 @@
+# Cron����ʽ
+
+## ����
+
+`NewLife.Threading.Cron` ��һ���������� Cron ����ʽ������ƥ�����������ж�ij��ʱ����Ƿ���������ܼ�����һ��/��һ�ε�ִ��ʱ�䡣
+
+��� Cron ��ȣ�NewLife.Cron ����������࣬�ʺ��ڶ�ʱ������ϵͳ��ʹ�á�
+
+**�����ռ�**: `NewLife.Threading`
+**Դ��**: [NewLife.Core/Threading/Cron.cs](https://github.com/NewLifeX/X/blob/master/NewLife.Core/Threading/Cron.cs)
+
+---
+
+## ��������
+
+### �����ͽ���
+
+```csharp
+using NewLife.Threading;
+
+// ��ʽ1������ʱ�������ʽ
+var cron = new Cron("0 0 2 * * 1-5");
+
+// ��ʽ2���ȴ��������
+var cron2 = new Cron();
+cron2.Parse("*/5 * * * * *");
+```
+
+### �ж�ʱ���Ƿ�ƥ��
+
+```csharp
+var cron = new Cron("0 0 2 * * 1-5"); // ÿ���������賿2��
+
+// �жϵ�ǰʱ���Ƿ���ϱ���ʽ
+if (cron.IsTime(DateTime.Now))
+{
+ Console.WriteLine("������ִ��ʱ��");
+}
+
+// �ж��ض�ʱ��
+var time = new DateTime(2025, 1, 6, 2, 0, 0); // 2025��1��6��(��һ) 2��
+if (cron.IsTime(time))
+{
+ Console.WriteLine("��ʱ�����Ϲ���");
+}
+```
+
+### ������һ��ִ��ʱ��
+
+```csharp
+var cron = new Cron("0 0 2 * * *"); // ÿ���賿2��
+var next = cron.GetNext(DateTime.Now);
+Console.WriteLine($"��һ��ִ��ʱ�䣺{next}");
+
+// ������һ��ִ��ʱ��
+var prev = cron.GetPrevious(DateTime.Now);
+Console.WriteLine($"��һ��ִ��ʱ�䣺{prev}");
+```
+
+---
+
+## ����ʽ�
+
+### ����ʽ�ṹ
+
+Cron ����ʽ�ɿո�ָ��� **6 ���ֶ�**��ɣ���7���ֶ�"��"�ݲ�֧�֣���
+
+```
+�� �� ʱ �� �� ����
+```
+
+| �ֶ� | ��Χ | ˵�� |
+|-----|------|------|
+| �� | 0-59 | ���� |
+| �� | 0-59 | ������ |
+| ʱ | 0-23 | Сʱ����24Сʱ�ƣ� |
+| �� | 1-31 | ÿ�µĵڼ��� |
+| �� | 1-12 | �·� |
+| ���� | 0-6 | ���ڼ���0=���գ�1=��һ��...��6=������ |
+
+**ʾ��**��
+```
+0 30 8 * * 1-5 // ÿ�������� 8:30
+0 0 */2 * * * // ÿ2Сʱ����
+0 0 0 1 * * // ÿ��1���賿
+*/10 * * * * * // ÿ10��
+```
+
+### ֧�ֵ��
+
+#### 1. ͨ��� `*`
+
+��ʾ���п��ܵ�ֵ��
+
+```
+* * * * * * // ÿ��
+0 * * * * * // ÿ���ӵ�0��
+0 0 * * * * // ÿСʱ��0��0��
+```
+
+#### 2. ռλ�� `?`
+
+��ָ��ֵ��ʵ���ϵȼ��� `*`����Ҫ���ڼ��� Quartz ������ Cron ʵ�֡�
+
+```
+0 0 0 ? * 1 // ÿ��һ�賿�����ڲ�ָ����
+```
+
+#### 3. ö�� `a,b,c`
+
+�г����ָ��ֵ��
+
+```
+0 0 0 1,15 * * // ÿ��1�ź�15���賿
+0 0 8,12,18 * * * // ÿ��8�㡢12�㡢18��
+```
+
+#### 4. ��Χ `a-b`
+
+��ʾһ��������Χ�������䣩��
+
+```
+0 0 2 * * 1-5 // ��һ�������賿2��
+0 0 9-17 * * * // ÿ��9�㵽17�㣨ÿСʱ��
+```
+
+#### 5. ���� `*/n`��`a/n`��`a-b/n`
+
+��ʾ����һ��������ѡ��ֵ��
+
+- `*/n`����0��ʼ��ÿ��nѡһ��
+- `a/n`����a��ʼ��ÿ��nѡһ��
+- `a-b/n`����a��b��Χ�ڣ�ÿ��nѡһ��
+
+```
+*/2 * * * * * // ÿ2�루0,2,4,6...�룩
+5/20 * * * * * // ÿ���ӵ�5�롢25�롢45��
+0 */30 * * * * // ÿ30����
+0 0 0 */5 * * // ÿ5��
+```
+
+#### 6. �ڼ������ڼ� `d#k` �� `d#Lk`
+
+�������ֶ�֧�֣����ڱ���"ÿ�µڼ������ڼ�"��
+
+- `d#k`��ÿ�µ�k������d
+- `d#Lk`��ÿ�µ�����k������d
+
+```
+0 0 0 ? ? 1#1 // ÿ�µ�1����һ�賿
+0 0 0 ? ? 5#2 // ÿ�µ�2�������賿
+0 0 0 ? ? 1#L1 // ÿ�����1����һ�賿
+0 0 0 ? ? 3-5#L2 // ÿ�µ�����2�������������賿
+```
+
+**ע��**��`#` ��Ὣ������ģ 7����˿����� 7 ��ʾ���ա�
+
+---
+
+## ����ƫ��
+
+### Ĭ����Ϊ
+
+Cron Ĭ�ϲ��� Linux/.NET ���
+- `0` ��ʾ���� (Sunday)
+- `1` ��ʾ��һ (Monday)
+- `2` ��ʾ�ܶ� (Tuesday)
+- ...
+- `6` ��ʾ���� (Saturday)
+
+### Sunday ����
+
+`Sunday` �������ڵ���"����"��Ӧ������ƫ�ƣ�
+
+```csharp
+var cron = new Cron();
+cron.Sunday = 0; // Ĭ��ֵ��0��ʾ����
+// 0=���գ�1=��һ��2=�ܶ�...
+
+cron.Sunday = 1; // ��Ϊ1��ʾ����
+// 1=���գ�2=��һ��3=�ܶ�...
+```
+
+**ʹ�ý���**��
+- һ������±���Ĭ�� `Sunday = 0` ����
+- �����Ҫ��������ϵͳ����ijЩ���ݿ⣩���ɵ���Ϊ `Sunday = 1`
+- `Parse` ���������Զ��ƶ� `Sunday`����Ҫ�ֶ�����
+
+---
+
+## ���� API
+
+### IsTime - �ж�ʱ���Ƿ�ƥ��
+
+```csharp
+/// <summary>ָ��ʱ���Ƿ�λ�ڱ���ʽ֮��</summary>
+/// <param name="time">Ҫ�жϵ�ʱ��</param>
+/// <returns>�Ƿ�ƥ��</returns>
+public Boolean IsTime(DateTime time)
+```
+
+**ʾ��**��
+```csharp
+var cron = new Cron("0 0 2 * * 1-5");
+var time = new DateTime(2025, 1, 6, 2, 0, 0);
+if (cron.IsTime(time))
+{
+ Console.WriteLine("ƥ��");
+}
+```
+
+**ע������**��
+- �ж�ʱ�ῼ���롢�֡�ʱ���ա��¡���������ά��
+- �����ֶ�֧��"�ڼ������ڼ�"�ĸ����ж�
+- ʱ��ᰴ�� `Sunday` ���Խ������ڼ���
+
+### GetNext - ��ȡ��һ��ִ��ʱ��
+
+```csharp
+/// <summary>���ָ��ʱ��֮�����һ��ִ��ʱ�䣬����ָ��ʱ��</summary>
+/// <param name="time">�Ӹ�ʱ�������һ���������һ��ִ��ʱ��</param>
+/// <returns>��һ��ִ��ʱ�䣨�뼶�������û��ƥ������Сʱ��</returns>
+public DateTime GetNext(DateTime time)
+```
+
+**ʾ��**��
+```csharp
+var cron = new Cron("0 0 2 * * *"); // ÿ���賿2��
+var now = DateTime.Now;
+var next = cron.GetNext(now);
+Console.WriteLine($"��һ��ִ�У�{next:yyyy-MM-dd HH:mm:ss}");
+```
+
+**ע������**��
+- �������ʱ����к��루�� 09:14:23.456��������ǰ���뵽��һ�루09:14:24�����ټ���
+- ���ص�ʱ�䲻���������ʱ�䱾��
+- ���1�����Ҳ���ƥ��ʱ�䣬���� `DateTime.MinValue`
+- **���ܾ���**���÷���ͨ������������ң�������1�꣬���ʺ�Ƶ������
+
+### GetPrevious - ��ȡ��һ��ִ��ʱ��
+
+```csharp
+/// <summary>�����ָ��ʱ����ϱ���ʽ�������ȥʱ�䣨�뼶��</summary>
+/// <param name="time">��ʱ��</param>
+/// <returns>��һ��ִ��ʱ�䣬���û��ƥ������Сʱ��</returns>
+public DateTime GetPrevious(DateTime time)
+```
+
+**ʾ��**��
+```csharp
+var cron = new Cron("0 0 2 * * *");
+var prev = cron.GetPrevious(DateTime.Now);
+Console.WriteLine($"��һ��ִ�У�{prev:yyyy-MM-dd HH:mm:ss}");
+```
+
+### ���� Cron ����
+
+```csharp
+/// <summary>��һ��Cron����ʽ����ȡ��һ��ִ��ʱ��</summary>
+public static DateTime GetNext(String[] crons, DateTime time)
+
+/// <summary>��һ��Cron����ʽ����ȡǰһ��ִ��ʱ��</summary>
+public static DateTime GetPrevious(String[] crons, DateTime time)
+```
+
+**ʾ��**��
+```csharp
+var crons = new[] { "0 0 2 * * *", "0 0 14 * * *" }; // ÿ��2���14��
+var next = Cron.GetNext(crons, DateTime.Now);
+Console.WriteLine($"��һ��ִ�У�{next}");
+```
+
+---
+
+## ��� TimerX ʹ��
+
+Cron �����ʹ�ó�������� `TimerX` ʵ�ֶ�ʱ����
+
+```csharp
+using NewLife.Threading;
+
+// ���� Cron ��ʱ����ÿ������������8��ִ��
+var timer = new TimerX(state =>
+{
+ Console.WriteLine($"ִ������{DateTime.Now}");
+}, null, "0 0 8 * * 1-5");
+
+// ֧�ֶ�� Cron ����ʽ���ֺŷָ�
+var timer2 = new TimerX(state =>
+{
+ Console.WriteLine("ִ������");
+}, null, "0 0 2 * * 1-5;0 0 3 * * 6"); // ������2�㣬����3��
+
+// ʹ����ϼǵ��ͷ�
+timer.Dispose();
+timer2.Dispose();
+```
+
+�����[TimerX ʹ���ֲ�](timerx-����ʱ��TimerX.md)
+
+---
+
+## ���ñ���ʽʾ��
+
+### ÿ��/ÿ��/ÿʱ
+
+```
+* * * * * * // ÿ��
+*/2 * * * * * // ÿ2��
+*/5 * * * * * // ÿ5��
+0 * * * * * // ÿ����
+0 */5 * * * * // ÿ5����
+0 */15 * * * * // ÿ15����
+0 */30 * * * * // ÿ30����
+0 0 * * * * // ÿСʱ
+0 0 */2 * * * // ÿ2Сʱ
+```
+
+### ÿ��̶�ʱ��
+
+```
+0 0 0 * * * // ÿ���賿0��
+0 0 1 * * * // ÿ���賿1��
+0 30 8 * * * // ÿ��8��30��
+0 0 12 * * * // ÿ������12��
+0 0 23 * * * // ÿ������23��
+0 0 0,12 * * * // ÿ��0���12��
+0 0 8,12,18 * * * // ÿ��8�㡢12�㡢18��
+```
+
+### ������/��ĩ
+
+```
+0 0 9 * * 1-5 // ÿ������������9��
+0 0 2 * * 1-5 // ÿ���������賿2��
+0 0 10 * * 6,0 // ÿ����ĩ�����������գ�10��
+0 0 0 * * 1 // ÿ��һ�賿
+0 0 0 * * 5 // ÿ�����賿
+```
+
+### ÿ�¹̶�����
+
+```
+0 0 0 1 * * // ÿ��1���賿
+0 0 0 15 * * // ÿ��15���賿
+0 0 0 1,15 * * // ÿ��1�ź�15���賿
+0 0 0 L * * // ÿ�����һ���賿��������������
+```
+
+### ���ӳ���
+
+```
+0 0 2 * * 1-5 // ÿ���������賿2��
+5/20 * * * * * // ÿ���ӵ�5�롢25�롢45��
+0 0 0 ? ? 1#1 // ÿ�µ�1����һ�賿
+0 0 0 ? ? 5#L1 // ÿ�����1�������賿
+0 0 0 1-7 * 1 // ÿ�µ�һ����һ�賿����һ��д����
+```
+
+---
+
+## ע������������
+
+### ���ܿ���
+
+`GetNext` �� `GetPrevious` ����ͨ��**�������**ʵ�֣������ص㣺
+- **�ʺϳ���**����Ƶ�ʵ��ã��綨ʱ�����ʼ��ʱ������һ��ִ��ʱ��
+- **���ʺϳ���**����Ƶ���á�ʵʱ·�����ȵ����
+- **��������**��������1�꣨Լ3ǧ���ѭ����
+
+**����**��
+- �� `TimerX` ��ʼ��ʱ����һ����һ��ִ��ʱ�伴��
+- ������ѭ����Ƶ������
+- ��������ܳ�������������ʵ���㷨
+
+### ��֧������ֶ�
+
+��ǰʵ�ֽ�֧��6���ֶΣ��롢�֡�ʱ���ա��¡����ڣ���**��֧�ֵ�7���ֶ�"��"**��
+
+### �ֶ�ȱʡ����
+
+- �������ʽ����6���ֶΣ�ȱʡ�ֶ�Ĭ��Ϊ `*`
+- ���磺`0 0 2 * *` �ᱻ����Ϊ `0 0 2 * * *`
+
+### �����ֶ�������
+
+- ���ڼ����� `Sunday` ����Ӱ��
+- `#` ��Ὣ������ģ7����� 7 Ҳ���Ա�ʾ����
+- ���ڷ�Χ�� 0-6������� `Sunday` ����Ϊ 1-7��
+
+---
+
+## Դ�����
+
+### ��������
+
+```csharp
+public Boolean Parse(String expression)
+{
+ var ss = expression.Split([' '], StringSplitOptions.RemoveEmptyEntries);
+
+ // ������
+ if (!TryParse(ss[0], 0, 60, out var vs)) return false;
+ Seconds = vs;
+
+ // ������
+ if (!TryParse(ss.Length > 1 ? ss[1] : "*", 0, 60, out vs)) return false;
+ Minutes = vs;
+
+ // ... ���ν���ʱ���ա���
+
+ // �������ڣ��������
+ var weeks = new Dictionary<Int32, Int32>();
+ if (!TryParseWeek(ss.Length > 5 ? ss[5] : "*", 0, 7, weeks)) return false;
+ DaysOfWeek = weeks;
+
+ return true;
+}
+```
+
+### ƥ���ж�
+
+```csharp
+public Boolean IsTime(DateTime time)
+{
+ // ����ʱ���ж�
+ if (!Seconds.Contains(time.Second) ||
+ !Minutes.Contains(time.Minute) ||
+ !Hours.Contains(time.Hour) ||
+ !DaysOfMonth.Contains(time.Day) ||
+ !Months.Contains(time.Month))
+ return false;
+
+ // �����жϣ����� Sunday ƫ�ƣ�
+ var w = (Int32)time.DayOfWeek + Sunday;
+ if (!DaysOfWeek.TryGetValue(w, out var index)) return false;
+
+ // �ڼ������ڼ��жϣ�index > 0 ��ʾ�����ڼ�����< 0 ��ʾ������
+ // ... ������
+
+ return true;
+}
+```
+
+---
+
+## ��������
+
+### 1. ����ʽ����ʧ�ܣ�
+
+�����Ƿ���ȷ��
+- �ֶ������Ƿ�Ϊ6��������٣�ȱʡĬ��`*`��
+- ��Χֵ�Ƿ�����Ч��Χ��
+- ����ֵ��Ƿ���ȷ
+
+```csharp
+var cron = new Cron();
+if (!cron.Parse("0 0 2 * * 1-5"))
+{
+ Console.WriteLine("����ʧ��");
+}
+```
+
+### 2. GetNext ���� MinValue��
+
+˵��1�����Ҳ���ƥ���ʱ�䣬����ԭ��
+- ����ʽ����ì�ܣ��� `0 0 0 31 2 *` 2��û��31�ţ�
+- ���ں����ڳ�ͻ
+
+### 3. ���ڼ��㲻�ԣ�
+
+��� `Sunday` �������ã�
+```csharp
+var cron = new Cron("0 0 0 * * 1");
+cron.Sunday = 0; // ȷ��ƫ����
+```
+
+### 4. ����Ӱ����㣿
+
+`GetNext` ���Զ��������룬���϶��뵽��һ�룺
+```csharp
+var time = new DateTime(2025, 1, 1, 9, 14, 23, 456); // ������
+var next = cron.GetNext(time); // �� 09:14:24 ��ʼ����
+```
+
+---
+
+## �����
+
+- **TimerX �ĵ�**: [timerx-����ʱ��TimerX.md](timerx-����ʱ��TimerX.md)
+- **������Cron�ο�**: https://help.aliyun.com/document_detail/64769.html
+- **�����ĵ�**: https://newlifex.com/core/cron
+- **Դ��**: https://github.com/NewLifeX/X/blob/master/NewLife.Core/Threading/Cron.cs
+
+---
+
+## ������־
+
+- **2025-01**: �����ĵ���������ϸʾ����Դ�����
+- **2024**: ֧�� .NET 9.0
+- **2023**: ����������
+- **2022**: ��������Cron���㷽��
+- **2020**: ��ʼ�汾��֧�ֻ���Cron�
diff --git a/Doc/CsvDb.md "b/Doc/CSV\346\225\260\346\215\256\345\272\223CsvDb.md"
similarity index 100%
rename from Doc/CsvDb.md
rename to "Doc/CSV\346\225\260\346\215\256\345\272\223CsvDb.md"
diff --git a/Doc/CsvFile.md "b/Doc/CSV\346\226\207\344\273\266CsvFile.md"
similarity index 100%
rename from Doc/CsvFile.md
rename to "Doc/CSV\346\226\207\344\273\266CsvFile.md"
diff --git a/Doc/ExcelReader.md "b/Doc/Excel\350\257\273\345\217\226\345\231\250ExcelReader.md"
similarity index 100%
rename from Doc/ExcelReader.md
rename to "Doc/Excel\350\257\273\345\217\226\345\231\250ExcelReader.md"
diff --git a/Doc/ApiHttpClient.md "b/Doc/HTTP\345\256\242\346\210\267\347\253\257ApiHttpClient.md"
similarity index 100%
rename from Doc/ApiHttpClient.md
rename to "Doc/HTTP\345\256\242\346\210\267\347\253\257ApiHttpClient.md"
diff --git a/Doc/HttpServer.md "b/Doc/HTTP\346\234\215\345\212\241\347\253\257HttpServer.md"
similarity index 100%
rename from Doc/HttpServer.md
rename to "Doc/HTTP\346\234\215\345\212\241\347\253\257HttpServer.md"
diff --git "a/Doc/JSON\345\272\217\345\210\227\345\214\226.md" "b/Doc/JSON\345\272\217\345\210\227\345\214\226.md"
new file mode 100644
index 0000000..58691ca
--- /dev/null
+++ "b/Doc/JSON\345\272\217\345\210\227\345\214\226.md"
@@ -0,0 +1,418 @@
+# JSON ���л�
+
+## ����
+
+NewLife.Core �ṩ���������� JSON ���л��ͷ����л����ܣ�ͨ�� `JsonHelper` ��չ�������Է���ؽ��ж����� JSON �ַ�����ת�������� `FastJson` ʵ�֣�ͬʱ֧���л��� `System.Text.Json`��
+
+**�����ռ�**��`NewLife.Serialization`
+**�ĵ���ַ**��https://newlifex.com/core/json
+
+## ��������
+
+- **������**������ `FastJson` ʵ�֣����ⲿ����
+- **������**����Գ��������Ż���֧�ֶ����
+- **��չ����**��`ToJson()` �� `ToJsonEntity<T>()` �������
+- **�������**��֧���շ����������Կ�ֵ��������ʽ����
+- **����ת��**���Զ�������������ת��
+- **���л�**��֧���л��� `System.Text.Json` ʵ��
+
+## ���ٿ�ʼ
+
+### ���л�
+
+```csharp
+using NewLife.Serialization;
+
+// �������л�
+var user = new { Id = 1, Name = "����", Age = 25 };
+var json = user.ToJson();
+// {"Id":1,"Name":"����","Age":25}
+
+// ��ʽ�����
+var jsonIndented = user.ToJson(true);
+// {
+// "Id": 1,
+// "Name": "����",
+// "Age": 25
+// }
+
+// �շ�����
+var jsonCamel = user.ToJson(false, true, true);
+// {"id":1,"name":"����","age":25}
+```
+
+### �����л�
+
+```csharp
+using NewLife.Serialization;
+
+var json = """{"Id":1,"Name":"����","Age":25}""";
+
+// �����л�Ϊָ������
+var user = json.ToJsonEntity<User>();
+
+// �����л�Ϊ��̬�ֵ�
+var dict = json.DecodeJson();
+var name = dict["Name"]; // "����"
+```
+
+## API �ο�
+
+### ToJson - ���л�
+
+```csharp
+// �������л�
+public static String ToJson(this Object value, Boolean indented = false)
+
+// ��������
+public static String ToJson(this Object value, Boolean indented, Boolean nullValue, Boolean camelCase)
+
+// ʹ�����ö���
+public static String ToJson(this Object value, JsonOptions jsonOptions)
+```
+
+**����˵��**��
+- `indented`���Ƿ�������ʽ����Ĭ�� false
+- `nullValue`���Ƿ������ֵ��Ĭ�� true
+- `camelCase`���Ƿ�ʹ���շ�������Ĭ�� false
+
+**ʾ��**��
+```csharp
+var obj = new
+{
+ Id = 1,
+ Name = "����",
+ Description = (String?)null,
+ CreateTime = DateTime.Now
+};
+
+// Ĭ�����
+obj.ToJson();
+// {"Id":1,"Name":"����","Description":null,"CreateTime":"2025-01-07 12:00:00"}
+
+// ���Կ�ֵ
+obj.ToJson(false, false, false);
+// {"Id":1,"Name":"����","CreateTime":"2025-01-07 12:00:00"}
+
+// �շ����� + ��ʽ��
+obj.ToJson(true, true, true);
+```
+
+### ToJsonEntity - �����л�
+
+```csharp
+// ���ͷ���
+public static T? ToJsonEntity<T>(this String json)
+
+// ָ������
+public static Object? ToJsonEntity(this String json, Type type)
+```
+
+**ʾ��**��
+```csharp
+var json = """{"id":1,"name":"����","roles":["admin","user"]}""";
+
+// �����л�Ϊ��
+public class User
+{
+ public Int32 Id { get; set; }
+ public String Name { get; set; }
+ public String[] Roles { get; set; }
+}
+
+var user = json.ToJsonEntity<User>();
+Console.WriteLine(user.Name); // ����
+Console.WriteLine(user.Roles[0]); // admin
+```
+
+### DecodeJson - ����Ϊ�ֵ�
+
+```csharp
+public static IDictionary<String, Object?>? DecodeJson(this String json)
+```
+
+�� JSON �ַ�������Ϊ�ֵ䣬�����ڶ�̬���ʳ�����
+
+**ʾ��**��
+```csharp
+var json = """{"code":0,"data":{"id":1,"name":"test"},"message":"ok"}""";
+
+var dict = json.DecodeJson();
+var code = dict["code"].ToInt(); // 0
+var data = dict["data"] as IDictionary<String, Object>;
+var id = data["id"].ToInt(); // 1
+```
+
+### JsonOptions - ����ѡ��
+
+```csharp
+public class JsonOptions
+{
+ /// <summary>ʹ���շ�������Ĭ��false</summary>
+ public Boolean CamelCase { get; set; }
+
+ /// <summary>���Կ�ֵ��Ĭ��false</summary>
+ public Boolean IgnoreNullValues { get; set; }
+
+ /// <summary>����ѭ�����á�Ĭ��false</summary>
+ public Boolean IgnoreCycles { get; set; }
+
+ /// <summary>������ʽ����Ĭ��false</summary>
+ public Boolean WriteIndented { get; set; }
+
+ /// <summary>ʹ������ʱ���ʽ��Ĭ��false</summary>
+ public Boolean FullTime { get; set; }
+
+ /// <summary>ö��ʹ���ַ�����Ĭ��falseʹ������</summary>
+ public Boolean EnumString { get; set; }
+
+ /// <summary>��������Ϊ�ַ���������JS���ȶ�ʧ��Ĭ��false</summary>
+ public Boolean Int64AsString { get; set; }
+}
+```
+
+**ʾ��**��
+```csharp
+var options = new JsonOptions
+{
+ CamelCase = true,
+ IgnoreNullValues = true,
+ WriteIndented = true,
+ EnumString = true
+};
+
+var json = obj.ToJson(options);
+```
+
+### Format - ��ʽ�� JSON
+
+```csharp
+public static String Format(String json)
+```
+
+��ѹ���� JSON �ַ�����ʽ��Ϊ����ʽ��
+
+**ʾ��**��
+```csharp
+var json = """{"id":1,"name":"test","items":[1,2,3]}""";
+var formatted = JsonHelper.Format(json);
+// {
+// "id": 1,
+// "name": "test",
+// "items": [
+// 1,
+// 2,
+// 3
+// ]
+// }
+```
+
+## IJsonHost �ӿ�
+
+`IJsonHost` �� JSON ���л��ĺ��Ľӿڣ������л���ͬ��ʵ�֣�
+
+```csharp
+public interface IJsonHost
+{
+ IServiceProvider ServiceProvider { get; set; }
+ JsonOptions Options { get; set; }
+
+ String Write(Object value, Boolean indented = false, Boolean nullValue = true, Boolean camelCase = false);
+ String Write(Object value, JsonOptions jsonOptions);
+ Object? Read(String json, Type type);
+ Object? Convert(Object obj, Type targetType);
+ Object? Parse(String json);
+ IDictionary<String, Object?>? Decode(String json);
+}
+```
+
+### �л�ʵ��
+
+```csharp
+// Ĭ��ʹ�� FastJson
+JsonHelper.Default = new FastJson();
+
+// ��� System.Text.Json��.NET 5+��
+JsonHelper.Default = new SystemJson();
+```
+
+## ʹ�ó���
+
+### 1. Web API ���ݽ���
+
+```csharp
+// ���л���Ӧ
+public class ApiResult<T>
+{
+ public Int32 Code { get; set; }
+ public String? Message { get; set; }
+ public T? Data { get; set; }
+}
+
+var result = new ApiResult<User>
+{
+ Code = 0,
+ Message = "success",
+ Data = new User { Id = 1, Name = "test" }
+};
+
+// ʹ���շ�������ǰ���Ѻã�
+var json = result.ToJson(false, true, true);
+
+// ������Ӧ
+var response = json.ToJsonEntity<ApiResult<User>>();
+```
+
+### 2. ���������
+
+```csharp
+// ��ȡ JSON ����
+var json = File.ReadAllText("config.json");
+var config = json.ToJsonEntity<AppConfig>();
+
+// ��������
+var newJson = config.ToJson(true); // ��ʽ�������Ķ�
+File.WriteAllText("config.json", newJson);
+```
+
+### 3. ��־��¼
+
+```csharp
+public void LogRequest(Object request)
+{
+ // ���л��������������־
+ var json = request.ToJson();
+ XTrace.WriteLine($"Request: {json}");
+}
+```
+
+### 4. ��̬���ݴ���
+
+```csharp
+// ������ȷ���ṹ�� JSON
+var json = await httpClient.GetStringAsync(url);
+var dict = json.DecodeJson();
+
+if (dict.TryGetValue("error", out var error))
+{
+ throw new Exception(error?.ToString());
+}
+
+var data = dict["data"] as IDictionary<String, Object>;
+// ��̬�����ֶ�...
+```
+
+### 5. ���������;�������
+
+```csharp
+// JavaScript ����ȷ��ʾ���� 2^53 ������
+var options = new JsonOptions { Int64AsString = true };
+
+var obj = new { Id = 9007199254740993L };
+var json = obj.ToJson(options);
+// {"Id":"9007199254740993"} // �ַ�����ʽ�����⾫�ȶ�ʧ
+```
+
+## �������ʹ���
+
+### ����ʱ��
+
+```csharp
+var obj = new { Time = DateTime.Now };
+
+// Ĭ�ϸ�ʽ
+obj.ToJson();
+// {"Time":"2025-01-07 12:00:00"}
+
+// ���� ISO ��ʽ
+var options = new JsonOptions { FullTime = true };
+obj.ToJson(options);
+// {"Time":"2025-01-07T12:00:00.0000000+08:00"}
+```
+
+### ö��
+
+```csharp
+public enum Status { Pending, Active, Closed }
+
+var obj = new { Status = Status.Active };
+
+// Ĭ��ʹ������
+obj.ToJson();
+// {"Status":1}
+
+// ʹ���ַ���
+var options = new JsonOptions { EnumString = true };
+obj.ToJson(options);
+// {"Status":"Active"}
+```
+
+### �ֽ�����
+
+```csharp
+var obj = new { Data = new Byte[] { 1, 2, 3, 4 } };
+
+// Ĭ�� Base64
+obj.ToJson();
+// {"Data":"AQIDBA=="}
+```
+
+## ���ʵ��
+
+### 1. �������ö���
+
+```csharp
+// ����ȫ������
+public static class JsonConfig
+{
+ public static readonly JsonOptions Api = new()
+ {
+ CamelCase = true,
+ IgnoreNullValues = true
+ };
+
+ public static readonly JsonOptions Log = new()
+ {
+ WriteIndented = false,
+ IgnoreNullValues = true
+ };
+}
+
+// ʹ��
+var json = data.ToJson(JsonConfig.Api);
+```
+
+### 2. ������ֵ
+
+```csharp
+// �����л�ʱע���ֵ
+var user = json.ToJsonEntity<User>();
+if (user == null)
+{
+ // JSON Ϊ null �����ʧ��
+}
+
+// ��ʹ�ÿ��ַ������
+if (json.IsNullOrEmpty()) return;
+var user = json.ToJsonEntity<User>();
+```
+
+### 3. ������������
+
+```csharp
+// ���ڴ������ݣ����Ƿ�������
+// ����һ�������л�/�����л��������
+```
+
+## ����˵��
+
+- `FastJson` ��Գ��������Ż����ʺϴ����Ӧ��
+- ���ڸ�����Ҫ���л��� `System.Text.Json`
+- ����Ƶ������ `JsonOptions`�����鸴��
+- �ַ�������ʹ�ö�����Ż�
+
+## �������
+
+- [���������л� Binary](binary-���������л�Binary.md)
+- [XML ���л�](xml-XML���л�Xml.md)
+- [����ϵͳ Config](config-����ϵͳConfig.md)
diff --git a/Doc/README.md b/Doc/README.md
new file mode 100644
index 0000000..2d7f8a8
--- /dev/null
+++ b/Doc/README.md
@@ -0,0 +1,158 @@
+# NewLife.Core ʹ���ĵ�����
+
+## ����
+
+NewLife.Core ��һ��ȫ���ܵ� .NET ������⣬�ṩ��־�����硢���л������桢���̵߳Ȼ������ܡ�
+
+**�ֿ�**: https://github.com/NewLifeX/X
+**�ٷ��ĵ�**: https://newlifex.com/core
+**Nuget��**: [NewLife.Core](https://www.nuget.org/packages/NewLife.Core)
+
+---
+
+## �ĵ�Ŀ¼
+
+### ?? ʵ�ù���
+
+���Ĺ���ģ�飬Ӧ�ÿ����г��õĹ��ܡ�
+
+| ģ�� | �ĵ� | ˵�� |
+|------|------|------|
+| **��·��** | [��·��ITracer.md](��·��ITracer.md) | �ֲ�ʽAPM�����ܼ��������� |
+| **��־ϵͳ** | [��־ILog.md](��־ILog.md) | ͳһ��־�ӿڣ�֧���ļ�/����̨/������־ |
+| **����ʱ��** | [����ʱ��TimerX.md](����ʱ��TimerX.md) | ���뼶��ʱ����֧��Cron����ʽ |
+| **Cron����ʽ** | [Cron����ʽ.md](Cron����ʽ.md) | ������Cron�������´�ִ��ʱ��� |
+| **������Ϣ** | [������ϢMachineInfo.md](������ϢMachineInfo.md) | ��ȡӲ����ϵͳ��Ϣ |
+| **����ʱ��Ϣ** | [����ʱ��ϢRuntime.md](����ʱ��ϢRuntime.md) | Ӧ������ʱ��Ϣ |
+| **ƴ����** | [ƴ����PinYin.md](ƴ����PinYin.md) | ��Ч����תƴ�� |
+| **��������** | [��������ObjectContainer.md](��������ObjectContainer.md) | ����������ע�� |
+| **Ӧ������** | [������Ӧ������Host.md](������Ӧ������Host.md) | ��Ӧ�����������й� |
+| **������** | [������IPlugin.md](������IPlugin.md) | ͨ�ò��ϵͳ |
+| **�����Actor** | [�����Actor.md](�����Actor.md) | ������� |
+| **JWT����** | [Webͨ������JwtBuilder.md](Webͨ������JwtBuilder.md) | JWT��������֤ |
+| **�¼�����** | [�¼�����EventBus.md](�¼�����EventBus.md) | �������¼����ķ��� |
+
+### ?? ������չ
+
+���õ���չ���������ࡣ
+
+| ģ�� | �ĵ� | ˵�� |
+|------|------|------|
+| **����ת��** | [����ת��Utility.md](����ת��Utility.md) | ToInt/ToDateTime������ת�� |
+| **�ַ�����չ** | [�ַ�����չStringHelper.md](�ַ�����չStringHelper.md) | ��ȡ�����ܡ���ʽ���� |
+| **������չ** | [������չProcessHelper.md](������չProcessHelper.md) | ���̹�������Ϣ��ȡ |
+| **·����չ** | [·����չPathHelper.md](·����չPathHelper.md) | ��ƽ̨·������ |
+| **������չ** | [������չIOHelper.md](������չIOHelper.md) | IO��д�Ż� |
+| **��ȫ��չ** | [��ȫ��չSecurityHelper.md](��ȫ��չSecurityHelper.md) | �ӽ����㷨��װ |
+| **�����ٻ���** | [������DisposeBase.md](������DisposeBase.md) | ��Դ�ͷ�ģʽ |
+| **������չ** | [������չReflect.md](������չReflect.md) | �����ܷ��乤�� |
+
+### ?? ���������
+
+�������л������ù�����
+
+| ģ�� | �ĵ� | ˵�� |
+|------|------|------|
+| **JSON���л�** | [JSON���л�.md](JSON���л�.md) | ������JSON���� |
+| **XML���л�** | [XML���л�.md](XML���л�.md) | XML���л��뷴���л� |
+| **���������л�** | [���������л�Binary.md](���������л�Binary.md) | �����ܶ��������л� |
+| **CSV�ļ�** | [CSV�ļ�CsvFile.md](CSV�ļ�CsvFile.md) | CSV�ļ���д |
+| **CSV���ݿ�** | [CSV���ݿ�CsvDb.md](CSV���ݿ�CsvDb.md) | CSV��Ϊ���ݿ�ʹ�� |
+| **Excel��ȡ��** | [Excel��ȡ��ExcelReader.md](Excel��ȡ��ExcelReader.md) | ������Excel��ȡ |
+| **����ϵͳ** | [����ϵͳConfig.md](����ϵͳConfig.md) | ͳһ���ÿ�� |
+| **�����ṩ��** | [�����ṩ��IConfigProvider.md](�����ṩ��IConfigProvider.md) | �����ṩ����� |
+
+### ?? ���ݻ���
+
+���������ݴ������ߡ�
+
+| ģ�� | �ĵ� | ˵�� |
+|------|------|------|
+| **����ϵͳ** | [����ϵͳICache.md](����ϵͳICache.md) | ͳһ����ӿ� |
+| **�����** | [�����Pool.md](�����Pool.md) | �����ܶ����� |
+| **���ݰ�** | [���ݰ�IPacket.md](���ݰ�IPacket.md) | �㿽�����ݰ� |
+| **���ݼ�** | [���ݼ�DbTable.md](���ݼ�DbTable.md) | �ڴ����ݱ� |
+| **ѩ���㷨** | [ѩ���㷨Snowflake.md](ѩ���㷨Snowflake.md) | �ֲ�ʽΨһID |
+
+### ?? Span/Buffer ����
+
+�������ڴ�������ߡ�
+
+| ģ�� | �ĵ� | ˵�� |
+|------|------|------|
+| **Span����** | [Span����SpanHelper.md](Span����SpanHelper.md) | Span��չ���� |
+| **Span��ȡ��** | [Span��ȡ��SpanReader.md](Span��ȡ��SpanReader.md) | ��Ч�����ƶ�ȡ |
+| **Span���** | [Span���SpanWriter.md](Span���SpanWriter.md) | ��������� |
+| **������** | [������Buffers.md](������Buffers.md) | ���������� |
+| **�ػ�д����** | [�ػ�д����PooledByteBufferWriter.md](�ػ�д����PooledByteBufferWriter.md) | �ػ��ֽ�д���� |
+
+### ?? ����ͨ��
+
+����ͨ�ź�HTTP�ͻ��ˡ�
+
+| ģ�� | �ĵ� | ˵�� |
+|------|------|------|
+| **��������** | [��������NetServer.md](��������NetServer.md) | ������TCP/UDP����� |
+| **����ͻ���** | [����ͻ���NetClient.md](����ͻ���NetClient.md) | ͳһTCP/UDP�ͻ��˽ӿ� |
+| **ApiHttpClient** | [HTTP�ͻ���ApiHttpClient.md](HTTP�ͻ���ApiHttpClient.md) | ����Web API���� |
+| **HTTP�����** | [HTTP�����HttpServer.md](HTTP�����HttpServer.md) | ������HTTP������ |
+
+---
+
+## ���ٵ���
+
+### ���ù���
+
+- **��־���**: [��־ILog.md](��־ILog.md)
+- **��ʱ����**: [����ʱ��TimerX.md](����ʱ��TimerX.md) + [Cron����ʽ.md](Cron����ʽ.md)
+- **���ܼ��**: [��·��ITracer.md](��·��ITracer.md)
+- **Ӳ����Ϣ**: [������ϢMachineInfo.md](������ϢMachineInfo.md)
+- **����ע��**: [��������ObjectContainer.md](��������ObjectContainer.md)
+- **�����й�**: [������Ӧ������Host.md](������Ӧ������Host.md)
+- **���ݻ���**: [����ϵͳICache.md](����ϵͳICache.md)
+- **���ù���**: [����ϵͳConfig.md](����ϵͳConfig.md)
+
+### �ⲿ��Դ
+
+- **GitHub**: https://github.com/NewLifeX/X
+- **Nuget**: https://www.nuget.org/packages/NewLife.Core
+- **�ٷ��ĵ�**: https://newlifex.com/core
+- **QQȺ**: 1600800
+
+---
+
+## �ĵ��淶
+
+�����ĵ���ѭͳһ��ʽ��
+
+1. **����** - ���ܼ�Ҫ����
+2. **���ٿ�ʼ** - ��Сʾ������
+3. **����API** - �ӿ�/��/����˵��
+4. **ʹ�ó���** - ʵ��Ӧ��ʾ��
+5. **���ʵ��** - �Ƽ��÷�
+6. **ע������** - DZ������
+7. **��������** - FAQ
+8. **�ο�����** - ����ĵ�
+9. **������־** - �汾��ʷ
+
+---
+
+## ����ָ��
+
+��ӭ�����ĵ���
+
+1. Fork �ֿ�
+2. ��д���ĵ�����ѭ�����淶��`{���ı���}.md`
+3. �ύ Pull Request
+
+---
+
+## ���¼�¼
+
+- **2025-01-07**: �������л������á����桢����ص��ĵ�
+- **2025-01-06**: �����ĵ���ܣ���� 15 ƪ�����ĵ�
+- �ƻ���дԼ 45 ƪ�ĵ�
+
+---
+
+**ע��**: ���Ϊ"_��д_"���ĵ����ڱ�д�С�
diff --git a/Doc/SpanWriter.md "b/Doc/Span\345\206\231\345\205\245\345\231\250SpanWriter.md"
similarity index 100%
rename from Doc/SpanWriter.md
rename to "Doc/Span\345\206\231\345\205\245\345\231\250SpanWriter.md"
diff --git a/Doc/SpanReader.md "b/Doc/Span\350\257\273\345\217\226\345\231\250SpanReader.md"
similarity index 100%
rename from Doc/SpanReader.md
rename to "Doc/Span\350\257\273\345\217\226\345\231\250SpanReader.md"
diff --git a/Doc/SpanHelper.md "b/Doc/Span\350\276\205\345\212\251SpanHelper.md"
similarity index 100%
rename from Doc/SpanHelper.md
rename to "Doc/Span\350\276\205\345\212\251SpanHelper.md"
diff --git "a/Doc/Web\351\200\232\347\224\250\344\273\244\347\211\214JwtBuilder.md" "b/Doc/Web\351\200\232\347\224\250\344\273\244\347\211\214JwtBuilder.md"
new file mode 100644
index 0000000..301d20b
--- /dev/null
+++ "b/Doc/Web\351\200\232\347\224\250\344\273\244\347\211\214JwtBuilder.md"
@@ -0,0 +1,461 @@
+# Webͨ������ JwtBuilder
+
+## ����
+
+`JwtBuilder` �� NewLife.Core �е� JSON Web Token (JWT) ���ɺ���֤�����ࡣJWT ��һ�ֽ��ա����������Ƹ�ʽ���㷺���� Web API ��֤����Ȩ��JwtBuilder ֧�� HS256/HS384/HS512 �� RS256/RS384/RS512 �������㷨��
+
+**�����ռ�**��`NewLife.Web`
+**�ĵ���ַ**��https://newlifex.com/core/jwt
+
+## ��������
+
+- **���㷨֧��**��HS256��HS384��HS512��RS256��RS384��RS512
+- **������**��֧�� iss��sub��aud��exp��nbf��iat��jti �ȱ�����
+- **�Զ�������**��֧����������Я�������Զ�������
+- **ʱ����֤**���Զ���֤����ʱ�����Чʱ��
+- **����չ**��֧��ע���Զ���ǩ���㷨
+
+## ���ٿ�ʼ
+
+### ��������
+
+```csharp
+using NewLife.Web;
+
+var builder = new JwtBuilder
+{
+ Secret = "your-secret-key-at-least-32-characters",
+ Expire = DateTime.Now.AddHours(2), // 2Сʱ�����
+ Subject = "user123", // �û���ʶ
+ Issuer = "MyApp" // �䷢��
+};
+
+// �����Զ�������
+builder["role"] = "admin";
+builder["name"] = "����";
+
+// ��������
+var token = builder.Encode(new { });
+Console.WriteLine(token);
+```
+
+### ��֤����
+
+```csharp
+var builder = new JwtBuilder
+{
+ Secret = "your-secret-key-at-least-32-characters"
+};
+
+if (builder.TryDecode(token, out var message))
+{
+ Console.WriteLine($"�û�: {builder.Subject}");
+ Console.WriteLine($"��ɫ: {builder["role"]}");
+ Console.WriteLine($"����ʱ��: {builder.Expire}");
+}
+else
+{
+ Console.WriteLine($"��֤ʧ��: {message}");
+}
+```
+
+## API �ο�
+
+### ����
+
+#### ������
+
+```csharp
+/// <summary>�䷢�� (iss)</summary>
+public String? Issuer { get; set; }
+
+/// <summary>���������� (sub)���ɴ���û�ID</summary>
+public String? Subject { get; set; }
+
+/// <summary>���� (aud)</summary>
+public String? Audience { get; set; }
+
+/// <summary>����ʱ�� (exp)��Ĭ��2Сʱ</summary>
+public DateTime Expire { get; set; }
+
+/// <summary>��Чʱ�� (nbf)���ڴ�֮ǰ��Ч</summary>
+public DateTime NotBefore { get; set; }
+
+/// <summary>�䷢ʱ�� (iat)</summary>
+public DateTime IssuedAt { get; set; }
+
+/// <summary>���Ʊ�ʶ (jti)</summary>
+public String? Id { get; set; }
+```
+
+#### ��������
+
+```csharp
+/// <summary>�㷨��Ĭ��HS256</summary>
+public String Algorithm { get; set; }
+
+/// <summary>�������ͣ�Ĭ��JWT</summary>
+public String? Type { get; set; }
+
+/// <summary>��Կ</summary>
+public String? Secret { get; set; }
+
+/// <summary>�Զ���������</summary>
+public IDictionary<String, Object?> Items { get; }
+```
+
+#### ������
+
+```csharp
+// ��ȡ�������Զ�������
+public Object? this[String key] { get; set; }
+```
+
+### Encode - ��������
+
+```csharp
+public String Encode(Object payload)
+```
+
+�����ݱ���Ϊ JWT �����ַ�����
+
+**����**��
+- `payload`��Ҫ��������ݶ���
+
+**����ֵ**��JWT �����ַ���
+
+**ʾ��**��
+```csharp
+var builder = new JwtBuilder
+{
+ Secret = "my-secret-key-32-characters-long",
+ Expire = DateTime.Now.AddDays(7),
+ Subject = "user_001"
+};
+
+// ��ʽ1��ʹ�����Ժ�������
+builder["permissions"] = new[] { "read", "write" };
+var token1 = builder.Encode(new { });
+
+// ��ʽ2��ֱ�Ӵ������
+var token2 = builder.Encode(new
+{
+ userId = 123,
+ userName = "test",
+ permissions = new[] { "read", "write" }
+});
+```
+
+### TryDecode - ��֤����������
+
+```csharp
+public Boolean TryDecode(String token, out String? message)
+```
+
+��֤ JWT ���Ʋ��������ݡ�
+
+**����**��
+- `token`��JWT �����ַ���
+- `message`����֤ʧ��ʱ�Ĵ�����Ϣ
+
+**����ֵ**����֤�Ƿ�ɹ�
+
+**��֤����**��
+1. JWT ��ʽ�Ƿ���ȷ������ʽ��
+2. ǩ���Ƿ���Ч
+3. �Ƿ�����Ч����
+4. �Ƿ�����Ч
+
+**ʾ��**��
+```csharp
+var builder = new JwtBuilder
+{
+ Secret = "my-secret-key-32-characters-long"
+};
+
+if (builder.TryDecode(token, out var message))
+{
+ // ��֤�ɹ�����ȡ����
+ var userId = builder.Subject;
+ var expire = builder.Expire;
+ var permissions = builder["permissions"];
+}
+else
+{
+ // ��֤ʧ��
+ Console.WriteLine($"����: {message}");
+ // ���ܵĴ���:
+ // - "JWT��ʽ����ȷ"
+ // - "�����ѹ���"
+ // - "����δ��Ч"
+ // - "δ������Կ"
+}
+```
+
+### Parse - ����������֤
+
+```csharp
+public String[]? Parse(String token)
+```
+
+���������ƽṹ������֤ǩ����������Ҫ����֤ǰ��ȡ���ݵij�����
+
+**����ֵ**������ʽ���� [header, payload, signature]����ʽ���� null
+
+**ʾ��**��
+```csharp
+var builder = new JwtBuilder();
+var parts = builder.Parse(token);
+
+if (parts != null)
+{
+ // ���Զ�ȡ�㷨������ʱ���
+ Console.WriteLine($"�㷨: {builder.Algorithm}");
+ Console.WriteLine($"����: {builder.Expire}");
+
+ // Ȼ��������Կ����������֤
+ builder.Secret = "...";
+ if (builder.TryDecode(token, out _)) { }
+}
+```
+
+### RegisterAlgorithm - ע���Զ����㷨
+
+```csharp
+public static void RegisterAlgorithm(
+ String algorithm,
+ JwtEncodeDelegate encode,
+ JwtDecodeDelegate? decode)
+```
+
+ע���Զ���ǩ���㷨��
+
+**ʾ��**��
+```csharp
+// ע���Զ����㷨
+JwtBuilder.RegisterAlgorithm(
+ "ES256",
+ (data, secret) => ECDsaHelper.SignSha256(data, secret),
+ (data, secret, signature) => ECDsaHelper.VerifySha256(data, secret, signature)
+);
+
+// ʹ���Զ����㷨
+var builder = new JwtBuilder
+{
+ Algorithm = "ES256",
+ Secret = ecdsaPrivateKey
+};
+var token = builder.Encode(new { });
+```
+
+## ֧�ֵ��㷨
+
+| �㷨 | ���� | ��ԿҪ�� | ˵�� |
+|------|------|---------|------|
+| HS256 | HMAC | �Գ���Կ | Ĭ���㷨���ʺϴ�������� |
+| HS384 | HMAC | �Գ���Կ | �����Ĺ�ϣ |
+| HS512 | HMAC | �Գ���Կ | ��Ĺ�ϣ |
+| RS256 | RSA | ��˽Կ�� | �ǶԳƼ��ܣ��ʺϷֲ�ʽ |
+| RS384 | RSA | ��˽Կ�� | �����Ĺ�ϣ |
+| RS512 | RSA | ��˽Կ�� | ��Ĺ�ϣ |
+
+## ʹ�ó���
+
+### 1. API ��֤
+
+```csharp
+// ��¼�ӿ� - ��������
+[HttpPost("login")]
+public IActionResult Login(String username, String password)
+{
+ var user = ValidateUser(username, password);
+ if (user == null) return Unauthorized();
+
+ var builder = new JwtBuilder
+ {
+ Secret = Configuration["Jwt:Secret"],
+ Expire = DateTime.Now.AddHours(24),
+ Subject = user.Id.ToString(),
+ Issuer = "MyApi"
+ };
+ builder["role"] = user.Role;
+ builder["name"] = user.Name;
+
+ var token = builder.Encode(new { });
+ return Ok(new { token });
+}
+
+// ��֤�м��
+public class JwtMiddleware
+{
+ public async Task InvokeAsync(HttpContext context)
+ {
+ var token = context.Request.Headers["Authorization"]
+ .ToString().TrimStart("Bearer ");
+
+ if (!token.IsNullOrEmpty())
+ {
+ var builder = new JwtBuilder
+ {
+ Secret = _configuration["Jwt:Secret"]
+ };
+
+ if (builder.TryDecode(token, out _))
+ {
+ context.Items["UserId"] = builder.Subject;
+ context.Items["Role"] = builder["role"];
+ }
+ }
+
+ await _next(context);
+ }
+}
+```
+
+### 2. ˢ������
+
+```csharp
+public class TokenService
+{
+ public (String accessToken, String refreshToken) CreateTokenPair(User user)
+ {
+ // �������� - ������Ч
+ var accessBuilder = new JwtBuilder
+ {
+ Secret = _secret,
+ Expire = DateTime.Now.AddMinutes(15),
+ Subject = user.Id.ToString()
+ };
+ accessBuilder["type"] = "access";
+
+ // ˢ������ - ������Ч
+ var refreshBuilder = new JwtBuilder
+ {
+ Secret = _secret,
+ Expire = DateTime.Now.AddDays(7),
+ Subject = user.Id.ToString()
+ };
+ refreshBuilder["type"] = "refresh";
+
+ return (accessBuilder.Encode(new { }), refreshBuilder.Encode(new { }));
+ }
+
+ public String? RefreshAccessToken(String refreshToken)
+ {
+ var builder = new JwtBuilder { Secret = _secret };
+
+ if (!builder.TryDecode(refreshToken, out _)) return null;
+ if (builder["type"]?.ToString() != "refresh") return null;
+
+ // �����µķ�������
+ var newBuilder = new JwtBuilder
+ {
+ Secret = _secret,
+ Expire = DateTime.Now.AddMinutes(15),
+ Subject = builder.Subject
+ };
+ newBuilder["type"] = "access";
+
+ return newBuilder.Encode(new { });
+ }
+}
+```
+
+### 3. RSA �ǶԳ�ǩ��
+
+```csharp
+// �����ǩ����ʹ��˽Կ��
+var privateKey = File.ReadAllText("private.pem");
+var builder = new JwtBuilder
+{
+ Algorithm = "RS256",
+ Secret = privateKey,
+ Expire = DateTime.Now.AddHours(1),
+ Subject = "user123"
+};
+var token = builder.Encode(new { });
+
+// �ͻ���/����������֤��ʹ�ù�Կ��
+var publicKey = File.ReadAllText("public.pem");
+var verifier = new JwtBuilder
+{
+ Algorithm = "RS256",
+ Secret = publicKey
+};
+if (verifier.TryDecode(token, out var msg))
+{
+ Console.WriteLine($"��֤�ɹ�: {verifier.Subject}");
+}
+```
+
+## ���ʵ��
+
+### 1. ��ȫ����Կ����
+
+```csharp
+// ���Ƽ���Ӳ������Կ
+var builder = new JwtBuilder { Secret = "my-secret" };
+
+// �Ƽ��������û�������ȡ
+var builder = new JwtBuilder
+{
+ Secret = Environment.GetEnvironmentVariable("JWT_SECRET")
+ ?? Configuration["Jwt:Secret"]
+};
+```
+
+### 2. �����Ĺ���ʱ��
+
+```csharp
+// �������ƣ����ڣ�15����-2Сʱ��
+Expire = DateTime.Now.AddMinutes(30);
+
+// ˢ�����ƣ����ڣ�1-7�죩
+Expire = DateTime.Now.AddDays(7);
+
+// ��ס�����ƣ����ڣ�30�죩
+Expire = DateTime.Now.AddDays(30);
+```
+
+### 3. ������������
+
+```csharp
+// ���Ƽ�����Ŵ�������
+builder["userProfile"] = new { /* ����� */ };
+
+// �Ƽ�������ű�Ҫ��ʶ
+builder.Subject = user.Id.ToString(); // ��Ҫ����ʱ�����ݿ�
+builder["role"] = user.Role; // ���õ���Ȩ��Ϣ
+```
+
+### 4. ��֤��������
+
+```csharp
+if (builder.TryDecode(token, out var message))
+{
+ // ������֤�䷢��
+ if (builder.Issuer != "MyApp")
+ {
+ // �䷢�߲�ƥ��
+ }
+
+ // ������֤����
+ if (builder.Audience != "web-client")
+ {
+ // ���ڲ�ƥ��
+ }
+}
+```
+
+## JWT ��ȫע������
+
+1. **��Ҫ�洢��������**��JWT Ĭ�ϲ����ܣ�payload �ɱ� Base64 ����
+2. **ʹ�� HTTPS**����ֹ���Ʊ��м��˽ػ�
+3. **���ú�������ʱ��**���������Ʊ����õķ���
+4. **ʹ���㹻������Կ**��HS256 ���� 32 �ֽ�
+5. **��֤��������**������ iss��aud��exp ��
+
+## �������
+
+- [�ֲ�ʽ����ǩ������ TokenProvider](token_provider-�ֲ�ʽ����ǩ������TokenProvider.md)
+- [��ȫ��չ SecurityHelper](security_helper-��ȫ��չSecurityHelper.md)
diff --git "a/Doc/XML\345\272\217\345\210\227\345\214\226.md" "b/Doc/XML\345\272\217\345\210\227\345\214\226.md"
new file mode 100644
index 0000000..03734c3
--- /dev/null
+++ "b/Doc/XML\345\272\217\345\210\227\345\214\226.md"
@@ -0,0 +1,388 @@
+# XML ���л�
+
+## ����
+
+NewLife.Core �ṩ������ XML ���л��ͷ����л����ܣ�ͨ�� `XmlHelper` ��չ�������Է���ؽ��ж����� XML ��ת����֧���Զ�����ע�͡�����ģʽ��������ԣ��ر��ʺ������ļ�������
+
+**�����ռ�**��`NewLife.Xml`����չ��������`NewLife.Serialization`������ʵ�֣�
+**�ĵ���ַ**��https://newlifex.com/core/xml
+
+## ��������
+
+- **��� API**��`ToXml()` �� `ToXmlEntity<T>()` ��չ����
+- **ע��֧��**���Զ����� `Description` �� `DisplayName` ������Ϊע��
+- **����ģʽ**����ѡ���������л�Ϊ XML ���Զ���Ԫ��
+- **�������**��֧��ָ�������ʽ
+- **�ļ�����**��ֱ�����л����ļ�����ļ������л�
+
+## ���ٿ�ʼ
+
+### ���л�
+
+```csharp
+using NewLife.Xml;
+
+public class AppConfig
+{
+ public String Name { get; set; }
+ public Int32 Port { get; set; }
+ public Boolean Debug { get; set; }
+}
+
+var config = new AppConfig
+{
+ Name = "MyApp",
+ Port = 8080,
+ Debug = true
+};
+
+// ���л�Ϊ XML �ַ���
+var xml = config.ToXml();
+```
+
+**���**��
+```xml
+<?xml version="1.0" encoding="utf-8"?>
+<AppConfig>
+ <Name>MyApp</Name>
+ <Port>8080</Port>
+ <Debug>true</Debug>
+</AppConfig>
+```
+
+### �����л�
+
+```csharp
+using NewLife.Xml;
+
+var xml = """
+<?xml version="1.0" encoding="utf-8"?>
+<AppConfig>
+ <Name>MyApp</Name>
+ <Port>8080</Port>
+ <Debug>true</Debug>
+</AppConfig>
+""";
+
+var config = xml.ToXmlEntity<AppConfig>();
+Console.WriteLine(config.Name); // MyApp
+```
+
+## API �ο�
+
+### ToXml - ���л�
+
+```csharp
+// �������л�
+public static String ToXml(this Object obj, Encoding? encoding = null,
+ Boolean attachComment = false, Boolean useAttribute = false)
+
+// ��������
+public static String ToXml(this Object obj, Encoding encoding,
+ Boolean attachComment, Boolean useAttribute, Boolean omitXmlDeclaration)
+
+// �������
+public static void ToXml(this Object obj, Stream stream, Encoding? encoding = null,
+ Boolean attachComment = false, Boolean useAttribute = false)
+
+// ���л����ļ�
+public static void ToXmlFile(this Object obj, String file, Encoding? encoding = null,
+ Boolean attachComment = true)
+```
+
+**����˵��**��
+- `encoding`�������ʽ��Ĭ�� UTF-8
+- `attachComment`���Ƿ�ע�ͣ�ʹ�� Description/DisplayName��
+- `useAttribute`���Ƿ�ʹ�� XML ����ģʽ
+- `omitXmlDeclaration`���Ƿ�ʡ�� XML ����
+
+### ToXmlEntity - �����л�
+
+```csharp
+// ���ַ��������л�
+public static TEntity? ToXmlEntity<TEntity>(this String xml) where TEntity : class
+
+// ���������л�
+public static TEntity? ToXmlEntity<TEntity>(this Stream stream, Encoding? encoding = null)
+
+// ���ļ������л�
+public static TEntity? ToXmlFileEntity<TEntity>(this String file, Encoding? encoding = null)
+```
+
+## ʹ�ó���
+
+### 1. �����ļ�
+
+```csharp
+using System.ComponentModel;
+using NewLife.Xml;
+
+public class DatabaseConfig
+{
+ [Description("���ݿ��������ַ")]
+ public String Server { get; set; } = "localhost";
+
+ [Description("���ݿ�˿�")]
+ public Int32 Port { get; set; } = 3306;
+
+ [Description("���ݿ�����")]
+ public String Database { get; set; } = "mydb";
+
+ [Description("�û���")]
+ public String User { get; set; } = "root";
+
+ [Description("���ӳ�ʱ���룩")]
+ public Int32 Timeout { get; set; } = 30;
+}
+
+// �������ã���ע�ͣ�
+var config = new DatabaseConfig();
+config.ToXmlFile("db.config", attachComment: true);
+
+// ��������
+var loaded = "db.config".ToXmlFileEntity<DatabaseConfig>();
+```
+
+**���ɵ� XML**��
+```xml
+<?xml version="1.0" encoding="utf-8"?>
+<DatabaseConfig>
+ <!--���ݿ��������ַ-->
+ <Server>localhost</Server>
+ <!--���ݿ�˿�-->
+ <Port>3306</Port>
+ <!--���ݿ�����-->
+ <Database>mydb</Database>
+ <!--�û���-->
+ <User>root</User>
+ <!--���ӳ�ʱ���룩-->
+ <Timeout>30</Timeout>
+</DatabaseConfig>
+```
+
+### 2. ����ģʽ���
+
+```csharp
+public class Item
+{
+ public Int32 Id { get; set; }
+ public String Name { get; set; }
+ public Decimal Price { get; set; }
+}
+
+var item = new Item { Id = 1, Name = "��ƷA", Price = 99.9M };
+
+// Ԫ��ģʽ��Ĭ�ϣ�
+var xml1 = item.ToXml();
+// <Item><Id>1</Id><Name>��ƷA</Name><Price>99.9</Price></Item>
+
+// ����ģʽ
+var xml2 = item.ToXml(useAttribute: true);
+// <Item Id="1" Name="��ƷA" Price="99.9" />
+```
+
+### 3. ���Ӷ���
+
+```csharp
+public class Order
+{
+ public Int32 Id { get; set; }
+ public DateTime CreateTime { get; set; }
+ public Customer Customer { get; set; }
+ public List<OrderItem> Items { get; set; }
+}
+
+public class Customer
+{
+ public String Name { get; set; }
+ public String Phone { get; set; }
+}
+
+public class OrderItem
+{
+ public String ProductName { get; set; }
+ public Int32 Quantity { get; set; }
+ public Decimal Price { get; set; }
+}
+
+var order = new Order
+{
+ Id = 1001,
+ CreateTime = DateTime.Now,
+ Customer = new Customer { Name = "����", Phone = "13800138000" },
+ Items = new List<OrderItem>
+ {
+ new() { ProductName = "��ƷA", Quantity = 2, Price = 50 },
+ new() { ProductName = "��ƷB", Quantity = 1, Price = 100 }
+ }
+};
+
+var xml = order.ToXml();
+```
+
+### 4. ʡ�� XML ����
+
+```csharp
+// ʡ�� <?xml version="1.0" encoding="utf-8"?>
+var xml = obj.ToXml(Encoding.UTF8, false, false, true);
+```
+
+### 5. �ֵ����л�
+
+```csharp
+// �ַ����ֵ����ֱ�����л�
+var dict = new Dictionary<String, String>
+{
+ ["Key1"] = "Value1",
+ ["Key2"] = "Value2"
+};
+
+dict.ToXmlFile("settings.xml");
+```
+
+## Xml �ࣨ���÷���
+
+������Ҫ����ϸ���Ƶij���������ֱ��ʹ�� `Xml` �ࣺ
+
+```csharp
+using NewLife.Serialization;
+
+// ���л�
+var xml = new Xml
+{
+ Stream = stream,
+ Encoding = Encoding.UTF8,
+ UseAttribute = false,
+ UseComment = true,
+ EnumString = true // ö��ʹ���ַ���
+};
+xml.Write(obj);
+
+// �����л�
+var xml = new Xml
+{
+ Stream = stream,
+ Encoding = Encoding.UTF8
+};
+var result = xml.Read(typeof(MyClass));
+```
+
+### Xml ������
+
+```csharp
+public class Xml
+{
+ /// <summary>ʹ���������</summary>
+ public Boolean UseAttribute { get; set; }
+
+ /// <summary>ʹ��ע��</summary>
+ public Boolean UseComment { get; set; }
+
+ /// <summary>ö��ʹ���ַ�����Ĭ��true</summary>
+ public Boolean EnumString { get; set; }
+
+ /// <summary>XML�����</summary>
+ public XmlWriterSettings Setting { get; set; }
+}
+```
+
+## ����֧��
+
+### XmlRoot - ��Ԫ������
+
+```csharp
+[XmlRoot("config")]
+public class AppConfig
+{
+ public String Name { get; set; }
+}
+
+// ��� <config><Name>...</Name></config>
+```
+
+### XmlElement - Ԫ������
+
+```csharp
+public class User
+{
+ [XmlElement("user_name")]
+ public String Name { get; set; }
+}
+```
+
+### XmlAttribute - �������
+
+```csharp
+public class Item
+{
+ [XmlAttribute]
+ public Int32 Id { get; set; }
+
+ public String Name { get; set; }
+}
+
+// ��� <Item Id="1"><Name>...</Name></Item>
+```
+
+### XmlIgnore - �����ֶ�
+
+```csharp
+public class User
+{
+ public String Name { get; set; }
+
+ [XmlIgnore]
+ public String Password { get; set; } // �����л�
+}
+```
+
+## ���ʵ��
+
+### 1. �����ļ�ʹ��ע��
+
+```csharp
+// ����ʱ����ע��
+config.ToXmlFile("app.config", attachComment: true);
+
+// ʹ�� Description ��������˵��
+[Description("Ӧ�����ƣ�������־��ʶ")]
+public String AppName { get; set; }
+```
+
+### 2. �ļ�����ע������
+
+```csharp
+// ToXmlFile ���Զ�����Ŀ¼
+config.ToXmlFile("Config/app.xml");
+
+// ����ļ��Ƿ����
+if (File.Exists(file))
+{
+ var config = file.ToXmlFileEntity<AppConfig>();
+}
+```
+
+### 3. ����һ����
+
+```csharp
+// ����ͼ���ʹ����ͬ����
+var encoding = Encoding.UTF8;
+config.ToXmlFile("config.xml", encoding);
+var loaded = "config.xml".ToXmlFileEntity<AppConfig>(encoding);
+```
+
+## �� JSON �Ա�
+
+| ���� | XML | JSON |
+|------|-----|------|
+| �ɶ��� | ��ע������ | ������ |
+| ��� | �ϴ� | ��С |
+| ע��֧�� | ԭ��֧�� | ��֧�� |
+| �����ļ� | ? �Ƽ� | ? ���� |
+| API ���� | ? ���Ƽ� | ? �Ƽ� |
+
+## �������
+
+- [JSON ���л�](json-JSON���л�.md)
+- [����ϵͳ Config](config-����ϵͳConfig.md)
+- [���������л� Binary](binary-���������л�Binary.md)
diff --git a/Doc/EventBus.md "b/Doc/\344\272\213\344\273\266\346\200\273\347\272\277EventBus.md"
similarity index 100%
rename from Doc/EventBus.md
rename to "Doc/\344\272\213\344\273\266\346\200\273\347\272\277EventBus.md"
diff --git "a/Doc/\344\272\214\350\277\233\345\210\266\345\272\217\345\210\227\345\214\226Binary.md" "b/Doc/\344\272\214\350\277\233\345\210\266\345\272\217\345\210\227\345\214\226Binary.md"
new file mode 100644
index 0000000..11f8867
--- /dev/null
+++ "b/Doc/\344\272\214\350\277\233\345\210\266\345\272\217\345\210\227\345\214\226Binary.md"
@@ -0,0 +1,416 @@
+# ���������л� Binary
+
+## ����
+
+`Binary` �� NewLife.Core �еĸ����ܶ��������л��������ڽ��������л�Ϊ���յĶ����Ƹ�ʽ��Ӷ��������ݷ����л�Ϊ�����ر��ʺ�����ͨ�š�Э����������ݴ洢�ȶ����ܺ�����нϸ�Ҫ��ij�����
+
+**�����ռ�**��`NewLife.Serialization`
+**�ĵ���ַ**��https://newlifex.com/core/binary
+
+## ��������
+
+- **������**��ֱ�Ӳ����ֽ��������м��ʽת��
+- **���ո�ʽ**��֧��7λ�䳤���������������������
+- **�ֽ������**��֧�ִ��/С���ֽ���
+- **Э��֧��**��֧�� `FieldSize` ���Զ����ֶδ�С
+- **�汾����**��֧��Э��汾����
+- **��չ��ǿ**���������Զ��崦����
+
+## ���ٿ�ʼ
+
+### ���л�
+
+```csharp
+using NewLife.Serialization;
+
+public class User
+{
+ public Int32 Id { get; set; }
+ public String Name { get; set; }
+ public Int32 Age { get; set; }
+}
+
+var user = new User { Id = 1, Name = "����", Age = 25 };
+
+// �������л�
+var packet = Binary.FastWrite(user);
+var bytes = packet.ToArray();
+
+// ��ʹ����
+using var ms = new MemoryStream();
+Binary.FastWrite(user, ms);
+```
+
+### �����л�
+
+```csharp
+using NewLife.Serialization;
+
+var bytes = /* ���������� */;
+
+// ���ٷ����л�
+using var ms = new MemoryStream(bytes);
+var user = Binary.FastRead<User>(ms);
+```
+
+## API �ο�
+
+### Binary ��
+
+#### ����
+
+```csharp
+/// <summary>ʹ��7λ����������Ĭ��false��ʹ��</summary>
+public Boolean EncodeInt { get; set; }
+
+/// <summary>С���ֽ���Ĭ��false���</summary>
+public Boolean IsLittleEndian { get; set; }
+
+/// <summary>ʹ��ָ����С��FieldSizeAttribute���ԡ�Ĭ��false</summary>
+public Boolean UseFieldSize { get; set; }
+
+/// <summary>��С���ȡ���ѡ0/1/2/4��Ĭ��0��ʾѹ����������</summary>
+public Int32 SizeWidth { get; set; }
+
+/// <summary>�����ַ���ʱ���Ƿ������ͷ��0�ֽڡ�Ĭ��false</summary>
+public Boolean TrimZero { get; set; }
+
+/// <summary>Э��汾������֧�ֶ�汾Э�����л�</summary>
+public String? Version { get; set; }
+
+/// <summary>ʹ��������ʱ���ʽ��������ʽʹ��8���ֽڱ����������Ĭ��false</summary>
+public Boolean FullTime { get; set; }
+
+/// <summary>�ܵ��ֽ�������ȡ��д��</summary>
+public Int64 Total { get; set; }
+```
+
+#### FastWrite - �������л�
+
+```csharp
+// ���л�Ϊ���ݰ�
+public static IPacket FastWrite(Object value, Boolean encodeInt = true)
+
+// �������
+public static Int64 FastWrite(Object value, Stream stream, Boolean encodeInt = true)
+```
+
+**����**��
+- `value`��Ҫ���л��Ķ���
+- `encodeInt`���Ƿ�ʹ��7λ�䳤��������
+- `stream`��Ŀ����
+
+**ʾ��**��
+```csharp
+// ���� IPacket
+var packet = Binary.FastWrite(obj);
+var bytes = packet.ToArray();
+
+// ���
+using var ms = new MemoryStream();
+var length = Binary.FastWrite(obj, ms);
+```
+
+#### FastRead - ���ٷ����л�
+
+```csharp
+public static T? FastRead<T>(Stream stream, Boolean encodeInt = true)
+```
+
+**ʾ��**��
+```csharp
+using var ms = new MemoryStream(bytes);
+var obj = Binary.FastRead<MyClass>(ms);
+```
+
+### �����÷�
+
+```csharp
+// ���������
+var bn = new Binary
+{
+ EncodeInt = true, // ʹ��7λ����
+ IsLittleEndian = true, // С���ֽ���
+ UseFieldSize = true // ���� FieldSize ����
+};
+
+// ������
+bn.Stream = new MemoryStream();
+
+// �����
+bn.Write(obj);
+
+// ��ȡ���
+var bytes = bn.GetBytes();
+```
+
+```csharp
+// �����л�
+var bn = new Binary
+{
+ Stream = new MemoryStream(bytes),
+ EncodeInt = true
+};
+
+var obj = bn.Read<MyClass>();
+```
+
+## IAccessor �ӿ�
+
+������Ҫ�Զ������л��������ͣ�����ʵ�� `IAccessor` �ӿڣ�
+
+```csharp
+public interface IAccessor
+{
+ /// <summary>����������ȡ</summary>
+ Boolean Read(Stream stream, Object context);
+
+ /// <summary>�������</summary>
+ Boolean Write(Stream stream, Object context);
+}
+```
+
+**ʾ��**��
+```csharp
+public class CustomPacket : IAccessor
+{
+ public Byte Header { get; set; }
+ public Int16 Length { get; set; }
+ public Byte[] Data { get; set; }
+ public Byte Checksum { get; set; }
+
+ public Boolean Read(Stream stream, Object context)
+ {
+ var bn = context as Binary;
+
+ Header = bn.ReadByte();
+ Length = bn.Read<Int16>();
+ Data = bn.ReadBytes(Length);
+ Checksum = bn.ReadByte();
+
+ return true;
+ }
+
+ public Boolean Write(Stream stream, Object context)
+ {
+ var bn = context as Binary;
+
+ bn.Write(Header);
+ bn.Write((Int16)Data.Length);
+ bn.Write(Data);
+ bn.Write(Checksum);
+
+ return true;
+ }
+}
+```
+
+## FieldSize ����
+
+`FieldSizeAttribute` ����ָ���ֶεĹ̶���С����������ֶΣ�
+
+```csharp
+public class Protocol
+{
+ public Byte Header { get; set; }
+
+ [FieldSize(2)] // �̶�2�ֽ�
+ public Int16 Length { get; set; }
+
+ [FieldSize("Length")] // ��С�� Length �ֶξ���
+ public Byte[] Body { get; set; }
+
+ [FieldSize(4)] // �̶�4�ֽ��ַ���
+ public String Code { get; set; }
+}
+```
+
+## ʹ�ó���
+
+### 1. ���������
+
+```csharp
+public class TcpMessage
+{
+ public Byte Start { get; set; } = 0x7E;
+ public UInt16 MessageId { get; set; }
+ public UInt16 BodyLength { get; set; }
+
+ [FieldSize("BodyLength")]
+ public Byte[] Body { get; set; }
+
+ public Byte Checksum { get; set; }
+ public Byte End { get; set; } = 0x7E;
+}
+
+// ����
+var bn = new Binary(stream) { IsLittleEndian = false, UseFieldSize = true };
+var msg = bn.Read<TcpMessage>();
+
+// ����
+var msg = new TcpMessage { MessageId = 0x0001, Body = data };
+msg.BodyLength = (UInt16)data.Length;
+msg.Checksum = CalculateChecksum(msg);
+var packet = Binary.FastWrite(msg);
+```
+
+### 2. JT/T808 ��
+
+```csharp
+public class JT808Message
+{
+ public UInt16 MsgId { get; set; }
+ public UInt16 MsgAttr { get; set; }
+
+ [FieldSize(6)] // 2011��6�ֽڣ�2019��10�ֽ�
+ public String Phone { get; set; }
+
+ public UInt16 SeqNo { get; set; }
+ public Byte[] Body { get; set; }
+}
+
+// 2011�汾
+var bn = new Binary { UseFieldSize = true, Version = "2011" };
+var msg = bn.Read<JT808Message>();
+
+// 2019�汾
+var bn = new Binary { UseFieldSize = true, Version = "2019" };
+```
+
+### 3. ���ݴ洢
+
+```csharp
+public class Record
+{
+ public Int64 Id { get; set; }
+ public DateTime CreateTime { get; set; }
+ public Byte[] Data { get; set; }
+}
+
+// ���浽�ļ�
+using var fs = File.Create("data.bin");
+foreach (var record in records)
+{
+ Binary.FastWrite(record, fs);
+}
+
+// �������
+using var fs = File.OpenRead("data.bin");
+var list = new List<Record>();
+while (fs.Position < fs.Length)
+{
+ var record = Binary.FastRead<Record>(fs);
+ list.Add(record);
+}
+```
+
+### 4. ���������л�
+
+```csharp
+// ���� Binary ʵ������Ƶ������
+var bn = new Binary { EncodeInt = true };
+
+foreach (var item in items)
+{
+ bn.Stream = new MemoryStream();
+ bn.Write(item);
+ var bytes = bn.GetBytes();
+ // ���� bytes...
+}
+```
+
+## 7λ�䳤����
+
+`EncodeInt = true` ʱ������ʹ��7λ�䳤���룬����������С��ֵ�Ĵ洢�ռ䣺
+
+| ֵ��Χ | �ֽ��� |
+|--------|--------|
+| 0 ~ 127 | 1 �ֽ� |
+| 128 ~ 16383 | 2 �ֽ� |
+| 16384 ~ 2097151 | 3 �ֽ� |
+| 2097152 ~ 268435455 | 4 �ֽ� |
+| ���� | 5 �ֽ� |
+
+```csharp
+// ���ñ䳤����
+var bn = new Binary { EncodeInt = true };
+bn.Stream = new MemoryStream();
+bn.Write(100); // 1�ֽ�
+bn.Write(1000); // 2�ֽ�
+bn.Write(100000); // 3�ֽ�
+```
+
+## �ֽ���
+
+```csharp
+// ����ֽ��������ֽ���Ĭ�ϣ�
+var bn = new Binary { IsLittleEndian = false };
+bn.Write((Int32)0x12345678); // ���: 12 34 56 78
+
+// С���ֽ���Intel x86��
+var bn = new Binary { IsLittleEndian = true };
+bn.Write((Int32)0x12345678); // ���: 78 56 34 12
+```
+
+## ���ʵ��
+
+### 1. Э�����ͳһ����
+
+```csharp
+public static class BinaryConfig
+{
+ public static Binary CreateReader(Stream stream) => new Binary(stream)
+ {
+ EncodeInt = false,
+ IsLittleEndian = false,
+ UseFieldSize = true
+ };
+
+ public static Binary CreateWriter() => new Binary
+ {
+ EncodeInt = false,
+ IsLittleEndian = false,
+ UseFieldSize = true
+ };
+}
+```
+
+### 2. ������
+
+```csharp
+var bn = new Binary(stream);
+try
+{
+ var obj = bn.Read<MyClass>();
+}
+catch (EndOfStreamException)
+{
+ // ���ݲ�����
+}
+```
+
+### 3. ���ʣ������
+
+```csharp
+var bn = new Binary(stream);
+
+// ����Ƿ����㹻����
+if (bn.CheckRemain(10)) // ������Ҫ10�ֽ�
+{
+ var data = bn.ReadBytes(10);
+}
+```
+
+## ���ܶԱ�
+
+| ���л���ʽ | ��� | �ٶ� | ���ó��� |
+|-----------|------|------|---------|
+| Binary | ��С | ��� | Э�顢�洢 |
+| JSON | �е� | �е� | API������ |
+| XML | ��� | ���� | ���á��ĵ� |
+
+## �������
+
+- [JSON ���л�](json-JSON���л�.md)
+- [XML ���л�](xml-XML���л�.md)
+- [���ݰ� IPacket](packet-���ݰ�IPacket.md)
diff --git "a/Doc/\345\217\215\345\260\204\346\211\251\345\261\225Reflect.md" "b/Doc/\345\217\215\345\260\204\346\211\251\345\261\225Reflect.md"
new file mode 100644
index 0000000..ca2aa4e
--- /dev/null
+++ "b/Doc/\345\217\215\345\260\204\346\211\251\345\261\225Reflect.md"
@@ -0,0 +1,542 @@
+# ������չ Reflect
+
+## ����
+
+`Reflect` �� NewLife.Core �еĸ����ܷ��乤���࣬�ṩ���ͻ�ȡ���������á����Զ�д�������ȹ��ܡ�֧��˽�г�Ա���ʡ����Դ�Сдƥ�䣬��ͨ�� `IReflect` �ӿ�֧�ֿ��滻�ķ���ʵ�֡�
+
+**�����ռ�**��`NewLife.Reflection`
+**�ĵ���ַ**��https://newlifex.com/core/reflect
+
+## ��������
+
+- **������**��Ĭ��ʵ�ֻ��ڻ��棬֧���л�Ϊ Emit ������ʵ��
+- **������**�����з���������չ������ʽ�ṩ
+- **������**��֧��˽�г�Ա����̬��Ա���̳г�Ա�ķ���
+- **�����**��֧�ֺ��Դ�Сд�ij�Աƥ��
+- **����չ**��ͨ�� `IReflect` �ӿ�֧���Զ���ʵ��
+
+## ���ٿ�ʼ
+
+```csharp
+using NewLife.Reflection;
+
+// ����ʵ��
+var obj = typeof(MyClass).CreateInstance();
+
+// ���÷���
+obj.Invoke("DoWork", "param1", 123);
+
+// ��ȡ����
+var value = obj.GetValue("Name");
+
+// ��������
+obj.SetValue("Name", "NewValue");
+
+// ����
+var target = new MyClass();
+target.Copy(source);
+```
+
+## API �ο�
+
+### ���ͻ�ȡ
+
+#### GetTypeEx
+
+```csharp
+public static Type? GetTypeEx(this String typeName)
+```
+
+�����������ƻ�ȡ���ͣ���������ǰĿ¼ DLL ���Զ����ء�
+
+**ʾ��**��
+```csharp
+// ��ȡϵͳ����
+var type1 = "System.String".GetTypeEx();
+
+// ��ȡ�������ռ������
+var type2 = "MyApp.Models.User".GetTypeEx();
+
+// ��ȡ������������
+var type3 = "MyApp.Models.User, MyApp".GetTypeEx();
+```
+
+### ��Ա��ȡ
+
+#### GetMethodEx
+
+```csharp
+public static MethodInfo? GetMethodEx(this Type type, String name, params Type[] paramTypes)
+```
+
+��ȡ������֧�ֲ�������ƥ�䡣
+
+**ʾ��**��
+```csharp
+// ��ȡ�η���
+var method1 = typeof(MyClass).GetMethodEx("DoWork");
+
+// ��ȡ���η���
+var method2 = typeof(MyClass).GetMethodEx("DoWork", typeof(String), typeof(Int32));
+```
+
+#### GetMethodsEx
+
+```csharp
+public static MethodInfo[] GetMethodsEx(this Type type, String name, Int32 paramCount = -1)
+```
+
+��ȡָ�����Ƶķ������ϣ�֧�ְ������������ˡ�
+
+**ʾ��**��
+```csharp
+// ��ȡ������Ϊ DoWork �ķ���
+var methods1 = typeof(MyClass).GetMethodsEx("DoWork");
+
+// ��ȡ��������Ϊ 2 �� DoWork ����
+var methods2 = typeof(MyClass).GetMethodsEx("DoWork", 2);
+```
+
+#### GetPropertyEx
+
+```csharp
+public static PropertyInfo? GetPropertyEx(this Type type, String name, Boolean ignoreCase = false)
+```
+
+��ȡ���ԣ�����˽�С���̬�������Ա��
+
+**ʾ��**��
+```csharp
+// ��ȷƥ��
+var prop1 = typeof(MyClass).GetPropertyEx("Name");
+
+// ���Դ�Сд
+var prop2 = typeof(MyClass).GetPropertyEx("name", true);
+
+// ��ȡ˽������
+var prop3 = typeof(MyClass).GetPropertyEx("_internalValue");
+```
+
+#### GetFieldEx
+
+```csharp
+public static FieldInfo? GetFieldEx(this Type type, String name, Boolean ignoreCase = false)
+```
+
+��ȡ�ֶΣ�����˽�С���̬�������Ա��
+
+**ʾ��**��
+```csharp
+var field = typeof(MyClass).GetFieldEx("_count");
+```
+
+#### GetMemberEx
+
+```csharp
+public static MemberInfo? GetMemberEx(this Type type, String name, Boolean ignoreCase = false)
+```
+
+��ȡ��Ա�����Ի��ֶΣ������ȷ������ԡ�
+
+**ʾ��**��
+```csharp
+var member = typeof(MyClass).GetMemberEx("Name", true);
+```
+
+#### GetFields / GetProperties
+
+```csharp
+public static IList<FieldInfo> GetFields(this Type type, Boolean baseFirst)
+public static IList<PropertyInfo> GetProperties(this Type type, Boolean baseFirst)
+```
+
+��ȡ�������л����ֶ�/�����б���
+
+**����˵��**��
+- `baseFirst`���Ƿ�����Ա��������
+
+**ʾ��**��
+```csharp
+// ��ȡ���п����л����ԣ���������
+var props = typeof(MyClass).GetProperties(baseFirst: true);
+
+// ��ȡ���п����л��ֶ�
+var fields = typeof(MyClass).GetFields(baseFirst: false);
+```
+
+### ʵ�������뷽������
+
+#### CreateInstance
+
+```csharp
+public static Object? CreateInstance(this Type type, params Object?[] parameters)
+```
+
+���䴴��ָ�����͵�ʵ����
+
+**ʾ��**��
+```csharp
+// �����ι��캯��
+var obj1 = typeof(MyClass).CreateInstance();
+
+// ���ô��ι��캯��
+var obj2 = typeof(MyClass).CreateInstance("name", 123);
+```
+
+#### Invoke
+
+```csharp
+public static Object? Invoke(this Object target, String name, params Object?[] parameters)
+public static Object? Invoke(this Object? target, MethodBase method, params Object?[]? parameters)
+```
+
+������÷�����
+
+**ʾ��**��
+```csharp
+var obj = new MyClass();
+
+// ����ʵ������
+var result = obj.Invoke("Calculate", 10, 20);
+
+// ���þ�̬������target Ϊ���ͣ�
+var result2 = typeof(MyClass).Invoke("StaticMethod", "param");
+
+// ����˽�з���
+var result3 = obj.Invoke("PrivateMethod");
+```
+
+#### TryInvoke
+
+```csharp
+public static Boolean TryInvoke(this Object target, String name, out Object? value, params Object?[] parameters)
+```
+
+���Ե��÷�����������ʱ���� false �����׳��쳣��
+
+**ʾ��**��
+```csharp
+if (obj.TryInvoke("MaybeExists", out var result, "param"))
+{
+ Console.WriteLine($"���: {result}");
+}
+else
+{
+ Console.WriteLine("����������");
+}
+```
+
+#### InvokeWithParams
+
+```csharp
+public static Object? InvokeWithParams(this Object? target, MethodBase method, IDictionary? parameters)
+```
+
+ʹ���ֵ�������÷������ʺϲ�����ƥ�䳡����
+
+**ʾ��**��
+```csharp
+var parameters = new Dictionary<String, Object>
+{
+ ["name"] = "test",
+ ["count"] = 10
+};
+var result = obj.InvokeWithParams(method, parameters);
+```
+
+### ���Զ�д
+
+#### GetValue
+
+```csharp
+public static Object? GetValue(this Object target, String name, Boolean throwOnError = true)
+public static Object? GetValue(this Object? target, MemberInfo member)
+```
+
+��ȡ����/�ֶ�ֵ��
+
+**ʾ��**��
+```csharp
+var obj = new MyClass { Name = "test" };
+
+// �����ƻ�ȡ
+var name = obj.GetValue("Name");
+
+// ������ʱ���� null �������쳣
+var value = obj.GetValue("NotExists", throwOnError: false);
+
+// ����Ա��ȡ
+var prop = typeof(MyClass).GetPropertyEx("Name");
+var name2 = obj.GetValue(prop);
+```
+
+#### SetValue
+
+```csharp
+public static Boolean SetValue(this Object target, String name, Object? value)
+public static void SetValue(this Object target, MemberInfo member, Object? value)
+```
+
+��������/�ֶ�ֵ��
+
+**ʾ��**��
+```csharp
+var obj = new MyClass();
+
+// ����������
+obj.SetValue("Name", "newValue");
+
+// ����Ա����
+var prop = typeof(MyClass).GetPropertyEx("Name");
+obj.SetValue(prop, "anotherValue");
+
+// ����Ƿ����óɹ�
+if (obj.SetValue("MaybeExists", "value"))
+{
+ Console.WriteLine("���óɹ�");
+}
+```
+
+### ����
+
+#### Copy
+
+```csharp
+public static void Copy(this Object target, Object src, Boolean deep = false, params String[] excludes)
+public static void Copy(this Object target, IDictionary<String, Object?> dic, Boolean deep = false)
+```
+
+��Դ������ֵ俽�����ݵ�Ŀ�����
+
+**����˵��**��
+- `deep`���Ƿ���ȿ���������ֵ�������ã�
+- `excludes`��Ҫ�ų��ij�Ա����
+
+**ʾ��**��
+```csharp
+var source = new User { Name = "����", Age = 25 };
+var target = new UserDto();
+
+// dz����
+target.Copy(source);
+
+// ���
+target.Copy(source, deep: true);
+
+// �ų�ijЩ�ֶ�
+target.Copy(source, excludes: "Password", "Secret");
+
+// ���ֵ俽��
+var dic = new Dictionary<String, Object?>
+{
+ ["Name"] = "����",
+ ["Age"] = 30
+};
+target.Copy(dic);
+```
+
+### ������
+
+#### GetElementTypeEx
+
+```csharp
+public static Type? GetElementTypeEx(this Type type)
+```
+
+��ȡ���͵�Ԫ�����ͣ����ϡ�����ȣ���
+
+**ʾ��**��
+```csharp
+typeof(List<String>).GetElementTypeEx() // typeof(String)
+typeof(String[]).GetElementTypeEx() // typeof(String)
+typeof(Dictionary<String, Int32>).GetElementTypeEx() // typeof(KeyValuePair<String, Int32>)
+```
+
+#### ChangeType
+
+```csharp
+public static Object? ChangeType(this Object? value, Type conversionType)
+public static TResult? ChangeType<TResult>(this Object? value)
+```
+
+����ת����
+
+**ʾ��**��
+```csharp
+// ����ת��
+var num = "123".ChangeType<Int32>(); // 123
+var date = "2024-01-15".ChangeType<DateTime>();
+
+// �Ƿ���ת��
+var value = "true".ChangeType(typeof(Boolean));
+```
+
+#### GetName
+
+```csharp
+public static String GetName(this Type type, Boolean isfull = false)
+```
+
+��ȡ���͵��Ѻ����ơ�
+
+**ʾ��**��
+```csharp
+typeof(List<String>).GetName() // "List<String>"
+typeof(List<String>).GetName(true) // "System.Collections.Generic.List<System.String>"
+typeof(Dictionary<String, Int32>).GetName() // "Dictionary<String, Int32>"
+```
+
+## ʹ�ó���
+
+### 1. ORM ʵ��ӳ��
+
+```csharp
+public class EntityMapper
+{
+ public T Map<T>(IDataReader reader) where T : new()
+ {
+ var entity = new T();
+ var props = typeof(T).GetProperties(baseFirst: false);
+
+ foreach (var prop in props)
+ {
+ var ordinal = reader.GetOrdinal(prop.Name);
+ if (ordinal >= 0 && !reader.IsDBNull(ordinal))
+ {
+ var value = reader.GetValue(ordinal);
+ entity.SetValue(prop, value);
+ }
+ }
+
+ return entity;
+ }
+}
+```
+
+### 2. ���ð�
+
+```csharp
+public class ConfigBinder
+{
+ public void Bind(Object target, IConfiguration config)
+ {
+ var props = target.GetType().GetProperties(baseFirst: true);
+
+ foreach (var prop in props)
+ {
+ var value = config[prop.Name];
+ if (value != null)
+ {
+ var converted = value.ChangeType(prop.PropertyType);
+ target.SetValue(prop, converted);
+ }
+ }
+ }
+}
+```
+
+### 3. ���ϵͳ
+
+```csharp
+public class PluginLoader
+{
+ public IPlugin? LoadPlugin(String typeName)
+ {
+ var type = typeName.GetTypeEx();
+ if (type == null) return null;
+
+ return type.CreateInstance() as IPlugin;
+ }
+
+ public void InvokeAction(IPlugin plugin, String action, params Object[] args)
+ {
+ if (plugin.TryInvoke(action, out var result, args))
+ {
+ Console.WriteLine($"ִ�гɹ�: {result}");
+ }
+ }
+}
+```
+
+### 4. DTO ת��
+
+```csharp
+public static class DtoExtensions
+{
+ public static TDto ToDto<TDto>(this Object entity) where TDto : new()
+ {
+ var dto = new TDto();
+ dto.Copy(entity);
+ return dto;
+ }
+
+ public static void UpdateFrom(this Object entity, Object dto, params String[] excludes)
+ {
+ entity.Copy(dto, excludes: excludes);
+ }
+}
+
+// ʹ��
+var dto = user.ToDto<UserDto>();
+user.UpdateFrom(dto, "Id", "CreateTime");
+```
+
+## ���ʵ��
+
+### 1. ʹ�� TryInvoke �����쳣
+
+```csharp
+// ? �Ƽ���ʹ�� TryInvoke
+if (obj.TryInvoke("Method", out var result))
+{
+ // �������
+}
+
+// ? ���Ƽ����������쳣
+try
+{
+ var result = obj.Invoke("Method");
+}
+catch (XException) { }
+```
+
+### 2. ���淴��Ԫ����
+
+```csharp
+// ? �Ƽ������� PropertyInfo
+private static readonly PropertyInfo _nameProp = typeof(User).GetPropertyEx("Name");
+
+public String GetName(User user) => user.GetValue(_nameProp) as String;
+
+// ? ���Ƽ���ÿ�ζ�����
+public String GetName(User user) => user.GetValue("Name") as String;
+```
+
+### 3. ʹ�ú��Դ�Сдƥ��
+
+```csharp
+// ���� JSON �����л��ȳ���
+var value = obj.GetValue("username", throwOnError: false);
+if (value == null)
+{
+ // ���Ժ��Դ�Сд
+ var member = obj.GetType().GetMemberEx("username", ignoreCase: true);
+ if (member != null) value = obj.GetValue(member);
+}
+```
+
+## ����˵��
+
+- Ĭ�� `DefaultReflect` ʵ��ʹ�û��棬�ʺϴ��������
+- ��Ƶ���䳡�����л�Ϊ `EmitReflect` ʵ�֣�
+ ```csharp
+ Reflect.Provider = new EmitReflect();
+ ```
+- `GetProperties` �� `GetFields` ����ᱻ����
+- ��Ա����ʹ���ֵ仺�棬�״η��ʺ����ܽӽ�ֱ�ӵ���
+
+## �������
+
+- [����ʱ��Ϣ Runtime](runtime-����ʱ��ϢRuntime.md)
+- [�ű����� ScriptEngine](script_engine-�ű�����ScriptEngine.md)
+- [�������� ObjectContainer](object_container-��������ObjectContainer.md)
diff --git "a/Doc/\345\217\257\351\224\200\346\257\201DisposeBase.md" "b/Doc/\345\217\257\351\224\200\346\257\201DisposeBase.md"
new file mode 100644
index 0000000..cf2f622
--- /dev/null
+++ "b/Doc/\345\217\257\351\224\200\346\257\201DisposeBase.md"
@@ -0,0 +1,462 @@
+# ������ DisposeBase
+
+## ����
+
+`DisposeBase` �� NewLife.Core ��ʵ�� `IDisposable` ģʽ�ij�����࣬�ṩ������Դ�ͷ�ģʽ����Ч��ֹ�ڴ����Դй©����ȷ���ͷ���ִֻ��һ�Σ���֧�������¼�֪ͨ��
+
+**�����ռ�**��`NewLife`
+**�ĵ���ַ**��https://newlifex.com/core/disposebase
+
+## ��������
+
+- **�� Dispose ģʽ**����ȷʵ�� `IDisposable` �ӿ�
+- **�����ͷű�֤**��ͨ��ԭ�Ӳ���ȷ���ͷ���ִֻ��һ��
+- **�ս���֧��**�������ǵ��� `Dispose` ʱ�ṩ�����ͷ�
+- **�����¼�**��֧���ڶ�������ʱ�����¼�֪ͨ
+- **��������**���ṩ `ThrowIfDisposed` �� `TryDispose` �ȸ�������
+
+## ���ٿ�ʼ
+
+```csharp
+using NewLife;
+
+// �̳� DisposeBase ʵ����Դ����
+public class MyResource : DisposeBase
+{
+ private Stream _stream;
+
+ public MyResource(String path)
+ {
+ _stream = File.OpenRead(path);
+ }
+
+ protected override void Dispose(Boolean disposing)
+ {
+ base.Dispose(disposing);
+
+ if (disposing)
+ {
+ // �ͷ��й���Դ
+ _stream?.Dispose();
+ _stream = null;
+ }
+ }
+}
+
+// ʹ�� using ����Զ��ͷ�
+using var resource = new MyResource("data.txt");
+```
+
+## API �ο�
+
+### IDisposable2 �ӿ�
+
+```csharp
+public interface IDisposable2 : IDisposable
+{
+ Boolean Disposed { get; }
+ event EventHandler OnDisposed;
+}
+```
+
+��չ�Ŀ����ٽӿڣ������� `Disposed` ״̬���Ժ������¼���
+
+### DisposeBase ��
+
+#### ����
+
+##### Disposed
+
+```csharp
+public Boolean Disposed { get; }
+```
+
+��ʾ�����Ƿ��ѱ��ͷš�
+
+**ʾ��**��
+```csharp
+var resource = new MyResource();
+Console.WriteLine(resource.Disposed); // False
+
+resource.Dispose();
+Console.WriteLine(resource.Disposed); // True
+```
+
+#### ����
+
+##### Dispose
+
+```csharp
+public void Dispose()
+```
+
+�ͷ���Դ�����ú�ᴥ�� `OnDisposed` �¼�����֪ͨ GC ���ٵ����ս�����
+
+##### Dispose(Boolean)
+
+```csharp
+protected virtual void Dispose(Boolean disposing)
+```
+
+ʵ�ʵ���Դ�ͷŷ������������ش˷���ʵ�־�����ͷ�����
+
+**����˵��**��
+- `disposing`��`true` ��ʾ�� `Dispose()` �������ã�Ӧ�ͷ�������Դ��`false` ��ʾ���ս������ã�ֻӦ�ͷŷ��й���Դ
+
+**����ʾ��**��
+```csharp
+protected override void Dispose(Boolean disposing)
+{
+ // 1. ���ȵ��û����
+ base.Dispose(disposing);
+
+ // 2. �ͷ��й���Դ�������� Dispose() ����ʱ��
+ if (disposing)
+ {
+ _managedResource?.Dispose();
+ _managedResource = null;
+ }
+
+ // 3. �ͷŷ��й���Դ������·����ִ�У�
+ if (_handle != IntPtr.Zero)
+ {
+ CloseHandle(_handle);
+ _handle = IntPtr.Zero;
+ }
+}
+```
+
+##### ThrowIfDisposed
+
+```csharp
+protected void ThrowIfDisposed()
+```
+
+�ڹ��������е��ã����������ͷ����׳� `ObjectDisposedException`��
+
+**ʾ��**��
+```csharp
+public class MyResource : DisposeBase
+{
+ public void DoWork()
+ {
+ ThrowIfDisposed(); // ���ͷ�ʱ�׳��쳣
+
+ // ִ��ʵ�ʹ���...
+ }
+}
+```
+
+#### �¼�
+
+##### OnDisposed
+
+```csharp
+public event EventHandler? OnDisposed
+```
+
+��������ʱ�������¼���
+
+**ע��**���¼��������ս����߳��д��������ķ�Ӧ���������ض��߳������ġ�
+
+**ʾ��**��
+```csharp
+var resource = new MyResource();
+resource.OnDisposed += (sender, e) =>
+{
+ Console.WriteLine("��Դ���ͷ�");
+};
+
+resource.Dispose(); // �������Դ���ͷ�
+```
+
+### DisposeHelper ������
+
+#### TryDispose
+
+```csharp
+public static Object? TryDispose(this Object? obj)
+```
+
+�������ٶ����������ʵ���� `IDisposable` ������� `Dispose` ������֧�ּ������ͣ��������������Ԫ�ء�
+
+**ʾ��**��
+```csharp
+// ���ٵ�������
+var stream = File.OpenRead("test.txt");
+stream.TryDispose();
+
+// ���ټ����е����ж���
+var streams = new List<Stream>
+{
+ File.OpenRead("a.txt"),
+ File.OpenRead("b.txt"),
+ File.OpenRead("c.txt")
+};
+streams.TryDispose(); // ����������
+```
+
+## ʹ�ó���
+
+### 1. ��������
+
+```csharp
+public class FileProcessor : DisposeBase
+{
+ private FileStream? _fileStream;
+ private StreamReader? _reader;
+
+ public FileProcessor(String path)
+ {
+ _fileStream = File.OpenRead(path);
+ _reader = new StreamReader(_fileStream);
+ }
+
+ public String ReadLine()
+ {
+ ThrowIfDisposed();
+ return _reader?.ReadLine() ?? String.Empty;
+ }
+
+ protected override void Dispose(Boolean disposing)
+ {
+ base.Dispose(disposing);
+
+ if (disposing)
+ {
+ _reader?.Dispose();
+ _reader = null;
+ _fileStream?.Dispose();
+ _fileStream = null;
+ }
+ }
+}
+```
+
+### 2. ������������
+
+```csharp
+public class TcpConnection : DisposeBase
+{
+ private Socket? _socket;
+ private NetworkStream? _stream;
+
+ public TcpConnection(String host, Int32 port)
+ {
+ _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+ _socket.Connect(host, port);
+ _stream = new NetworkStream(_socket, ownsSocket: false);
+ }
+
+ public void Send(Byte[] data)
+ {
+ ThrowIfDisposed();
+ _stream?.Write(data, 0, data.Length);
+ }
+
+ protected override void Dispose(Boolean disposing)
+ {
+ base.Dispose(disposing);
+
+ if (disposing)
+ {
+ _stream?.Dispose();
+ _stream = null;
+ _socket?.Dispose();
+ _socket = null;
+ }
+ }
+}
+```
+
+### 3. ��Դ�ع���
+
+```csharp
+public class ResourcePool<T> : DisposeBase where T : IDisposable
+{
+ private readonly ConcurrentBag<T> _pool = new();
+ private readonly Func<T> _factory;
+
+ public ResourcePool(Func<T> factory)
+ {
+ _factory = factory;
+ }
+
+ public T Rent()
+ {
+ ThrowIfDisposed();
+ return _pool.TryTake(out var item) ? item : _factory();
+ }
+
+ public void Return(T item)
+ {
+ if (Disposed)
+ {
+ item.Dispose();
+ return;
+ }
+ _pool.Add(item);
+ }
+
+ protected override void Dispose(Boolean disposing)
+ {
+ base.Dispose(disposing);
+
+ if (disposing)
+ {
+ while (_pool.TryTake(out var item))
+ {
+ item.Dispose();
+ }
+ }
+ }
+}
+```
+
+### 4. ���������¼�
+
+```csharp
+public class ResourceMonitor
+{
+ public void Monitor(IDisposable2 resource)
+ {
+ resource.OnDisposed += (sender, e) =>
+ {
+ var name = sender?.GetType().Name;
+ Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] {name} ���ͷ�");
+ };
+ }
+}
+
+// ʹ��
+var monitor = new ResourceMonitor();
+var resource = new MyResource();
+monitor.Monitor(resource);
+
+resource.Dispose(); // �����[12:30:45] MyResource ���ͷ�
+```
+
+## ���ʵ��
+
+### 1. ���ǵ��û����
+
+```csharp
+protected override void Dispose(Boolean disposing)
+{
+ // ? ���ȵ��û����
+ base.Dispose(disposing);
+
+ // Ȼ���ͷ��Լ�����Դ
+ if (disposing) { /* ... */ }
+}
+```
+
+### 2. ʹ�� using ���
+
+```csharp
+// ? �Ƽ���ʹ�� using ���ȷ���ͷ�
+using var resource = new MyResource();
+
+// ? ���Ƽ����ֶ����� Dispose����������
+var resource = new MyResource();
+try
+{
+ // ʹ����Դ
+}
+finally
+{
+ resource.Dispose();
+}
+```
+
+### 3. �ڹ��������м��״̬
+
+```csharp
+public class MyResource : DisposeBase
+{
+ public void DoWork()
+ {
+ // ? �ڷ�����ʼʱ����Ƿ����ͷ�
+ ThrowIfDisposed();
+
+ // ִ��ʵ�ʹ���
+ }
+}
+```
+
+### 4. ��ȷ�����йܺͷ��й���Դ
+
+```csharp
+protected override void Dispose(Boolean disposing)
+{
+ base.Dispose(disposing);
+
+ // �й���Դ������ disposing=true ʱ�ͷ�
+ if (disposing)
+ {
+ _managedObject?.Dispose();
+ }
+
+ // ���й���Դ�����������Ҫ�ͷ�
+ if (_nativeHandle != IntPtr.Zero)
+ {
+ NativeMethods.CloseHandle(_nativeHandle);
+ _nativeHandle = IntPtr.Zero;
+ }
+}
+```
+
+### 5. �������ս������׳��쳣
+
+```csharp
+// DisposeBase �Ѿ��������ս����е��쳣
+// ����� Dispose(Boolean) ����ҲӦ�ò�����ܵ��쳣
+protected override void Dispose(Boolean disposing)
+{
+ base.Dispose(disposing);
+
+ try
+ {
+ // �ͷ���Դ
+ }
+ catch (Exception ex)
+ {
+ // ��¼�����׳�
+ XTrace.WriteException(ex);
+ }
+}
+```
+
+## Dispose ģʽ���
+
+```
+���� Dispose()
+ ��
+ ��
+ Dispose(true)
+ ��
+ ������? �ͷ��й���Դ
+ ��
+ ������? �ͷŷ��й���Դ
+ ��
+ ������? ���� OnDisposed �¼�
+ ��
+ ������? GC.SuppressFinalize(this)
+ ��
+ ������? �ս������ٱ�����
+
+
+�ս��� ~DisposeBase() (������ǵ��� Dispose)
+ ��
+ ��
+ Dispose(false)
+ ��
+ ������? �ͷŷ��й���Դ
+ ��
+ ������? ���� OnDisposed �¼�
+```
+
+## �������
+
+- [����� ObjectPool](object_pool-�����ObjectPool.md)
+- [�������� ObjectContainer](object_container-��������ObjectContainer.md)
diff --git "a/Doc/\345\255\227\347\254\246\344\270\262\346\211\251\345\261\225StringHelper.md" "b/Doc/\345\255\227\347\254\246\344\270\262\346\211\251\345\261\225StringHelper.md"
new file mode 100644
index 0000000..249e5fe
--- /dev/null
+++ "b/Doc/\345\255\227\347\254\246\344\270\262\346\211\251\345\261\225StringHelper.md"
@@ -0,0 +1,516 @@
+# �ַ�����չ StringHelper
+
+## ����
+
+`StringHelper` �� NewLife.Core �е��ַ������������࣬�ṩ�˷ḻ���ַ�����չ�����������Ƚϡ���ȡ����֡�ƴ�ӡ��༭���������ȹ��ܣ���������ճ������е��ַ���������
+
+**�����ռ�**��`NewLife`
+**�ĵ���ַ**��https://newlifex.com/core/string_helper
+
+## ��������
+
+- **��ֵ��ȫ**�����з���������ȷ���� null �Ϳ��ַ���
+- **���Դ�Сд**���ṩ���ֺ��Դ�Сд�ıȽϷ���
+- **��Чʵ��**��ʹ�� `StringBuilder` �ػ���`Span<T>` �ȼ����Ż�����
+- **ģ��ƥ��**������ Levenshtein �༭����� LCS ������������㷨
+
+## ���ٿ�ʼ
+
+```csharp
+using NewLife;
+
+// ��ֵ�ж�
+var isEmpty = "".IsNullOrEmpty(); // true
+var isBlank = " ".IsNullOrWhiteSpace(); // true
+
+// ���Դ�Сд�Ƚ�
+var equal = "Hello".EqualIgnoreCase("hello"); // true
+
+// �ַ������
+var arr = "1,2,3".SplitAsInt(); // [1, 2, 3]
+var dic = "a=1;b=2".SplitAsDictionary(); // {a:1, b:2}
+
+// �ַ���ƴ��
+var str = new[] { 1, 2, 3 }.Join(","); // "1,2,3"
+```
+
+## API �ο�
+
+### ��ֵ�ж�
+
+#### IsNullOrEmpty
+
+```csharp
+public static Boolean IsNullOrEmpty(this String? value)
+```
+
+�ж��ַ����Ƿ�Ϊ null ����ַ�����
+
+**ʾ��**��
+```csharp
+String? s1 = null;
+s1.IsNullOrEmpty() // true
+"".IsNullOrEmpty() // true
+" ".IsNullOrEmpty() // false���ո���գ�
+"hello".IsNullOrEmpty() // false
+```
+
+#### IsNullOrWhiteSpace
+
+```csharp
+public static Boolean IsNullOrWhiteSpace(this String? value)
+```
+
+�ж��ַ����Ƿ�Ϊ null�����ַ�����������հ��ַ���
+
+**ʾ��**��
+```csharp
+String? s1 = null;
+s1.IsNullOrWhiteSpace() // true
+"".IsNullOrWhiteSpace() // true
+" ".IsNullOrWhiteSpace() // true
+"\t\n".IsNullOrWhiteSpace() // true
+"hello".IsNullOrWhiteSpace() // false
+```
+
+### �ַ����Ƚ�
+
+#### EqualIgnoreCase
+
+```csharp
+public static Boolean EqualIgnoreCase(this String? value, params String?[] strs)
+```
+
+���Դ�Сд�Ƚ��ַ����Ƿ�������һ����ѡ�ַ�����ȡ�
+
+**ʾ��**��
+```csharp
+"Hello".EqualIgnoreCase("hello") // true
+"Hello".EqualIgnoreCase("HELLO", "World") // true
+"Hello".EqualIgnoreCase("World", "Test") // false
+```
+
+#### StartsWithIgnoreCase
+
+```csharp
+public static Boolean StartsWithIgnoreCase(this String? value, params String?[] strs)
+```
+
+���Դ�Сд�ж��ַ����Ƿ�������һ����ѡǰ��ʼ��
+
+**ʾ��**��
+```csharp
+"HelloWorld".StartsWithIgnoreCase("hello") // true
+"HelloWorld".StartsWithIgnoreCase("HELLO", "Hi") // true
+```
+
+#### EndsWithIgnoreCase
+
+```csharp
+public static Boolean EndsWithIgnoreCase(this String? value, params String?[] strs)
+```
+
+���Դ�Сд�ж��ַ����Ƿ�������һ����ѡ��������
+
+**ʾ��**��
+```csharp
+"HelloWorld".EndsWithIgnoreCase("world") // true
+"HelloWorld".EndsWithIgnoreCase("WORLD", "Test") // true
+```
+
+### ͨ���ƥ��
+
+#### IsMatch
+
+```csharp
+public static Boolean IsMatch(this String pattern, String input, StringComparison comparisonType = StringComparison.CurrentCulture)
+```
+
+ʹ��ͨ���ģʽƥ���ַ�����֧�� `*`��ƥ�����ⳤ�ȣ��� `?`��ƥ�䵥���ַ�����
+
+**�ص�**��
+- ���������ʽ��������Ч
+- ʱ�临�Ӷ� O(n) ~ O(n*m)
+- ���蹹���������
+
+**ʾ��**��
+```csharp
+"*.txt".IsMatch("document.txt") // true
+"*.txt".IsMatch("document.doc") // false
+"file?.txt".IsMatch("file1.txt") // true
+"file?.txt".IsMatch("file12.txt") // false
+"*".IsMatch("anything") // true��ƥ�����У�
+"test*end".IsMatch("test123end") // true
+```
+
+### �ַ������
+
+#### Split����չ���أ�
+
+```csharp
+public static String[] Split(this String? value, params String[] separators)
+```
+
+��ָ���ָ�������ַ������Զ����˿���Ŀ��
+
+**ʾ��**��
+```csharp
+"a,b,,c".Split(",") // ["a", "b", "c"]���Զ����˿��
+"a;b,c".Split(",", ";") // ["a", "b", "c"]
+```
+
+#### SplitAsInt
+
+```csharp
+public static Int32[] SplitAsInt(this String? value, params String[] separators)
+```
+
+����ַ�����ת��Ϊ�������飬Ĭ��ʹ�ö��źͷֺ���Ϊ�ָ�����
+
+**�ص�**��
+- �Զ����˿ո�
+- �Զ�������Ч����
+- �����ظ���
+
+**ʾ��**��
+```csharp
+"1,2,3".SplitAsInt() // [1, 2, 3]
+"1, 2, 3".SplitAsInt() // [1, 2, 3]���Զ�ȥ���ո�
+"1;2;3".SplitAsInt() // [1, 2, 3]��֧�ַֺţ�
+"1,abc,3".SplitAsInt() // [1, 3]���������
+"1,1,2".SplitAsInt() // [1, 1, 2]�������ظ���
+```
+
+#### SplitAsDictionary
+
+```csharp
+public static IDictionary<String, String> SplitAsDictionary(
+ this String? value,
+ String nameValueSeparator = "=",
+ String separator = ";",
+ Boolean trimQuotation = false)
+```
+
+���ַ������Ϊ��ֵ���ֵ䡣
+
+**����˵��**��
+- `nameValueSeparator`����ֵ�ָ�����Ĭ�� `=`
+- `separator`����Ŀ�ָ�����Ĭ�� `;`
+- `trimQuotation`���Ƿ�ȥ��ֵ���˵�����
+
+**ʾ��**��
+```csharp
+// �����÷�
+"a=1;b=2".SplitAsDictionary()
+// { "a": "1", "b": "2" }
+
+// �Զ���ָ���
+"a:1,b:2".SplitAsDictionary(":", ",")
+// { "a": "1", "b": "2" }
+
+// ȥ������
+"name='test';value=\"123\"".SplitAsDictionary("=", ";", true)
+// { "name": "test", "value": "123" }
+
+// ����ʱʹ�����
+"value1;key=value2".SplitAsDictionary()
+// { "[0]": "value1", "key": "value2" }
+```
+
+> **��ʾ**�����ص��ֵ䲻���ִ�Сд��`StringComparer.OrdinalIgnoreCase`��
+
+### �ַ���ƴ��
+
+#### Join
+
+```csharp
+public static String Join(this IEnumerable value, String separator = ",")
+public static String Join<T>(this IEnumerable<T> value, String separator = ",", Func<T, Object?>? func = null)
+```
+
+������Ԫ��ƴ��Ϊ�ַ�����
+
+**ʾ��**��
+```csharp
+// �����÷�
+new[] { 1, 2, 3 }.Join() // "1,2,3"
+new[] { 1, 2, 3 }.Join(";") // "1;2;3"
+
+// ʹ��ת������
+var users = new[] { new { Name = "����" }, new { Name = "����" } };
+users.Join(",", u => u.Name) // "����,����"
+```
+
+#### Separate
+
+```csharp
+public static StringBuilder Separate(this StringBuilder sb, String separator)
+```
+
+�� `StringBuilder` �ӷָ�����������Կ�ͷ����һ�ε��ò��ӣ���
+
+**ʾ��**��
+```csharp
+var sb = new StringBuilder();
+sb.Separate(",").Append("a"); // "a"
+sb.Separate(",").Append("b"); // "a,b"
+sb.Separate(",").Append("c"); // "a,b,c"
+```
+
+### �ַ�����ȡ
+
+#### Substring����չ���أ�
+
+```csharp
+public static String Substring(this String str, String? after, String? before = null, Int32 startIndex = 0, Int32[]? positions = null)
+```
+
+���ַ����н�ȡָ�����֮������ݡ�
+
+**ʾ��**��
+```csharp
+// ��ȡ���֮�������
+"Hello[World]End".Substring("[") // "World]End"
+
+// ��ȡ�������֮�������
+"Hello[World]End".Substring("[", "]") // "World"
+
+// ��ȡ���֮ǰ������
+"Hello[World]End".Substring(null, "[") // "Hello"
+
+// ��ȡƥ��λ��
+var positions = new Int32[2];
+"Hello[World]End".Substring("[", "]", 0, positions);
+// positions[0] = 6��������ʼλ�ã�
+// positions[1] = 11�����ݽ���λ�ã�
+```
+
+#### Cut
+
+```csharp
+public static String Cut(this String str, Int32 maxLength, String? pad = null)
+```
+
+����Ƚ�ȡ�ַ�������ָ������ַ���
+
+**ʾ��**��
+```csharp
+"HelloWorld".Cut(8) // "HelloWor"
+"HelloWorld".Cut(8, "...") // "Hello..."���ܳ��Ȳ�����8��
+"Hi".Cut(8) // "Hi"�����㳤��ԭ�����أ�
+```
+
+#### TrimStart / TrimEnd
+
+```csharp
+public static String TrimStart(this String str, params String[] starts)
+public static String TrimEnd(this String str, params String[] ends)
+```
+
+���ַ�����ͷ/��β�Ƴ�ָ�������ַ����������ִ�Сд��֧�ֶ��ƥ�䡣
+
+**ʾ��**��
+```csharp
+"HelloHelloWorld".TrimStart("Hello") // "World"���Ƴ�����ƥ���ǰ��
+"WorldEndEnd".TrimEnd("End") // "World"
+```
+
+#### CutStart / CutEnd
+
+```csharp
+public static String CutStart(this String str, params String[] starts)
+public static String CutEnd(this String str, params String[] ends)
+```
+
+�Ƴ�ָ�����ַ�������֮ǰ/֮����������ݡ�
+
+**ʾ��**��
+```csharp
+"path/to/file.txt".CutStart("/") // "file.txt"
+"path/to/file.txt".CutEnd("/") // "path/to"
+```
+
+#### EnsureStart / EnsureEnd
+
+```csharp
+public static String EnsureStart(this String? str, String start)
+public static String EnsureEnd(this String? str, String end)
+```
+
+ȷ���ַ�����ָ�����ݿ�ʼ/������
+
+**ʾ��**��
+```csharp
+"world".EnsureStart("Hello") // "Helloworld"
+"Hello".EnsureStart("Hello") // "Hello"���Ѵ��������ӣ�
+
+"/api/users".EnsureEnd("/") // "/api/users/"
+"/api/users/".EnsureEnd("/") // "/api/users/"
+```
+
+#### TrimInvisible
+
+```csharp
+public static String? TrimInvisible(this String? value)
+```
+
+�Ƴ��ַ����еIJ��ɼ� ASCII �����ַ���0-31 �� 127����
+
+**ʾ��**��
+```csharp
+"Hello\x00World\x1F".TrimInvisible() // "HelloWorld"
+```
+
+### ����ת��
+
+#### GetBytes
+
+```csharp
+public static Byte[] GetBytes(this String? value, Encoding? encoding = null)
+```
+
+���ַ���ת��Ϊ�ֽ����飬Ĭ��ʹ�� UTF-8 ���롣
+
+**ʾ��**��
+```csharp
+"Hello".GetBytes() // UTF-8 ������ֽ�����
+"Hello".GetBytes(Encoding.ASCII) // ASCII ����
+"���".GetBytes(Encoding.UTF8) // UTF-8 ��������
+```
+
+### �����
+
+#### Levenshtein �༭����
+
+```csharp
+public static Int32 LevenshteinDistance(String str1, String str2)
+public static String[] LevenshteinSearch(String key, String[] words)
+```
+
+���������ַ���֮��ı༭���루���롢ɾ�����滻���������ٴ�������
+
+**ʾ��**��
+```csharp
+// ����༭����
+StringHelper.LevenshteinDistance("kitten", "sitting") // 3
+
+// �����
+var words = new[] { "apple", "application", "banana", "apply" };
+StringHelper.LevenshteinSearch("appl", words)
+// ["apple", "application", "apply"]
+```
+
+#### LCS �����������
+
+```csharp
+public static Int32 LCSDistance(String word, String[] keys)
+public static String[] LCSSearch(String key, String[] words)
+public static IEnumerable<T> LCSSearch<T>(this IEnumerable<T> list, String keys, Func<T, String> keySelector, Int32 count = -1)
+```
+
+��������������е�ģ���������ʺ������������顢�Զ���ȫ�ȳ�����
+
+**ʾ��**��
+```csharp
+var words = new[] { "HelloWorld", "HelloKitty", "GoodBye" };
+StringHelper.LCSSearch("Hello", words)
+// ["HelloKitty", "HelloWorld"]
+
+// ��������
+var users = new[] {
+ new { Id = 1, Name = "����" },
+ new { Id = 2, Name = "����" },
+ new { Id = 3, Name = "����" }
+};
+users.LCSSearch("��", u => u.Name, 2)
+// ��������������
+```
+
+#### Match ģ��ƥ��
+
+```csharp
+public static IList<KeyValuePair<T, Double>> Match<T>(this IEnumerable<T> list, String keys, Func<T, String> keySelector)
+public static IEnumerable<T> Match<T>(this IEnumerable<T> list, String keys, Func<T, String> keySelector, Int32 count, Double confidence = 0.5)
+```
+
+���������ʺ������ͷ���ģ��ƥ���㷨��
+
+**ʾ��**��
+```csharp
+var products = new[] { "iPhone 15", "iPhone 15 Pro", "Samsung Galaxy" };
+products.Match("iPhone", s => s, 2, 0.3)
+// ["iPhone 15", "iPhone 15 Pro"]
+```
+
+### ����ת����
+
+```csharp
+public static void Speak(this String value)
+public static void SpeakAsync(this String value)
+```
+
+����ϵͳ���������ʶ��ı����� Windows ƽ̨����
+
+**ʾ��**��
+```csharp
+"��ã�����".Speak(); // ͬ���ʶ�
+"��ã�����".SpeakAsync(); // �첽�ʶ�
+```
+
+## ���ʵ��
+
+### 1. ʹ�ÿ�ֵ��ȫ�ķ���
+
+```csharp
+// �Ƽ���ʹ����չ����
+if (str.IsNullOrEmpty()) return;
+
+// ���Ƽ�����Ҫ���� null
+if (str == null || str.Length == 0) return;
+```
+
+### 2. ���������ַ���
+
+```csharp
+// �����ַ�������
+var connStr = "Server=localhost;Database=test;User=root;Password=123456";
+var dic = connStr.SplitAsDictionary();
+var server = dic["Server"]; // "localhost"
+var database = dic["Database"]; // "test"
+```
+
+### 3. URL ��������
+
+```csharp
+var query = "name=test&age=18&tags=a,b,c";
+var dic = query.SplitAsDictionary("=", "&");
+var name = dic["name"]; // "test"
+var tags = dic["tags"].Split(","); // ["a", "b", "c"]
+```
+
+### 4. ʹ�� StringBuilder ��
+
+```csharp
+using NewLife.Collections;
+
+// �ӳ��л�ȡ StringBuilder
+var sb = Pool.StringBuilder.Get();
+sb.Append("Hello");
+sb.Separate(",").Append("World");
+
+// �����ַ������黹����
+var result = sb.Return(true); // "Hello,World"
+```
+
+## ����˵��
+
+- `IsNullOrEmpty` �� `IsNullOrWhiteSpace` ʹ�������Ż�
+- �ַ�����ֺ�ƴ��ʹ�� `StringBuilder` �أ������ڴ����
+- ͨ���ƥ��ʹ�õ�ָ������㷨�������������ʽ����
+- �༭�����㷨��Զ��ַ����Ż�
+
+## �������
+
+- [����ת�� Utility](utility-����ת��Utility.md)
+- [������չ IOHelper](io_helper-������չIOHelper.md)
+- [·����չ PathHelper](path_helper-·����չPathHelper.md)
diff --git "a/Doc/\345\256\211\345\205\250\346\211\251\345\261\225SecurityHelper.md" "b/Doc/\345\256\211\345\205\250\346\211\251\345\261\225SecurityHelper.md"
new file mode 100644
index 0000000..3ce0ea1
--- /dev/null
+++ "b/Doc/\345\256\211\345\205\250\346\211\251\345\261\225SecurityHelper.md"
@@ -0,0 +1,419 @@
+# ��ȫ��չ SecurityHelper
+
+## ����
+
+`SecurityHelper` �� NewLife.Core �еİ�ȫ�㷨�����࣬�ṩ���õĹ�ϣ�㷨���ԳƼ��ܡ��ǶԳƼ��ܵȹ��ܵ���չ������֧�� MD5��SHA ϵ�С�CRC��AES��DES��RSA �����������㷨��
+
+**�����ռ�**��`NewLife`
+**�ĵ���ַ**��https://newlifex.com/core/security_helper
+
+## ��������
+
+- **��ϣ�㷨**��MD5��SHA1��SHA256��SHA384��SHA512��CRC16��CRC32��Murmur128
+- **�ԳƼ���**��AES��DES��3DES��RC4��SM4
+- **�ǶԳƼ���**��RSA��DSA
+- **������**��ʹ���߳̾�̬���������㷨ʵ���������ظ�����
+- **������**�������㷨������չ������ʽ�ṩ
+
+## ���ٿ�ʼ
+
+```csharp
+using NewLife;
+
+// MD5 ��ϣ
+var hash = "password".MD5(); // 32λʮ�������ַ���
+var hash16 = "password".MD5_16(); // 16λʮ�������ַ���
+
+// SHA256 ��ϣ
+var sha = data.SHA256(); // �����ֽ�����
+var shaHex = data.SHA256().ToHex(); // תΪʮ�������ַ���
+
+// AES ����
+var encrypted = data.Encrypt(Aes.Create(), key);
+var decrypted = encrypted.Decrypt(Aes.Create(), key);
+
+// CRC ��
+var crc32 = data.Crc();
+var crc16 = data.Crc16();
+```
+
+## API �ο�
+
+### ��ϣ�㷨
+
+#### MD5
+
+```csharp
+public static Byte[] MD5(this Byte[] data)
+public static String MD5(this String data, Encoding? encoding = null)
+public static String MD5_16(this String data, Encoding? encoding = null)
+public static Byte[] MD5(this FileInfo file)
+```
+
+���� MD5 ɢ��ֵ��
+
+**ʾ��**��
+```csharp
+// �ַ��� MD5��32λ��
+"password".MD5() // "5F4DCC3B5AA765D61D8327DEB882CF99"
+
+// �ַ��� MD5��16λ��ȡ�м�8�ֽڣ�
+"password".MD5_16() // "5AA765D61D8327DE"
+
+// �ֽ����� MD5
+var data = Encoding.UTF8.GetBytes("hello");
+var hash = data.MD5(); // ���� 16 �ֽ�����
+
+// �ļ� MD5
+var fileHash = "large-file.zip".AsFile().MD5().ToHex();
+```
+
+#### SHA ϵ��
+
+```csharp
+public static Byte[] SHA1(this Byte[] data, Byte[]? key)
+public static Byte[] SHA256(this Byte[] data, Byte[]? key = null)
+public static Byte[] SHA384(this Byte[] data, Byte[]? key)
+public static Byte[] SHA512(this Byte[] data, Byte[]? key)
+```
+
+���� SHA ϵ��ɢ��ֵ����ѡ HMAC ��Կ��
+
+**ʾ��**��
+```csharp
+var data = Encoding.UTF8.GetBytes("hello");
+
+// ��ͨ��ϣ
+var sha256 = data.SHA256(); // 32 �ֽ�
+var sha512 = data.SHA512(null); // 64 �ֽ�
+
+// HMAC ��ϣ������Կ��
+var key = Encoding.UTF8.GetBytes("secret");
+var hmac256 = data.SHA256(key);
+var hmac512 = data.SHA512(key);
+```
+
+#### CRC ��
+
+```csharp
+public static UInt32 Crc(this Byte[] data)
+public static UInt16 Crc16(this Byte[] data)
+```
+
+���� CRC У��ֵ��
+
+**ʾ��**��
+```csharp
+var data = new Byte[] { 1, 2, 3, 4, 5 };
+
+var crc32 = data.Crc(); // UInt32 У��ֵ
+var crc16 = data.Crc16(); // UInt16 У��ֵ
+```
+
+#### Murmur128
+
+```csharp
+public static Byte[] Murmur128(this Byte[] data, UInt32 seed = 0)
+```
+
+���� Murmur128 �Ǽ��ܹ�ϣ�������ڹ�ϣ���ȳ������ٶȱ� MD5 ��ܶࡣ
+
+**ʾ��**��
+```csharp
+var hash = data.Murmur128(); // Ĭ������
+var hashWithSeed = data.Murmur128(12345); // ָ������
+```
+
+### �ԳƼ���
+
+#### Encrypt / Decrypt
+
+```csharp
+public static Byte[] Encrypt(this SymmetricAlgorithm sa, Byte[] data, Byte[]? pass = null, CipherMode mode = CipherMode.CBC, PaddingMode padding = PaddingMode.PKCS7)
+public static Byte[] Decrypt(this SymmetricAlgorithm sa, Byte[] data, Byte[]? pass = null, CipherMode mode = CipherMode.CBC, PaddingMode padding = PaddingMode.PKCS7)
+```
+
+�ԳƼ���/�������ݡ�
+
+**����˵��**��
+- `pass`�����루���Զ���䵽���ʵ���Կ���ȣ�
+- `mode`������ģʽ��CBC/ECB �ȣ���.NET Ĭ�� CBC��Java Ĭ�� ECB
+- `padding`�����ģʽ��Ĭ�� PKCS7����ͬ Java �� PKCS5��
+
+**ʾ��**��
+```csharp
+var data = Encoding.UTF8.GetBytes("Hello World!");
+var key = Encoding.UTF8.GetBytes("my-secret-key-16");
+
+// AES ���ܣ�CBC ģʽ��
+var encrypted = Aes.Create().Encrypt(data, key);
+
+// AES ����
+var decrypted = Aes.Create().Decrypt(encrypted, key);
+
+// ECB ģʽ���� Java ���ݣ�
+var encryptedEcb = Aes.Create().Encrypt(data, key, CipherMode.ECB);
+var decryptedEcb = Aes.Create().Decrypt(encryptedEcb, key, CipherMode.ECB);
+
+// DES ����
+var desKey = Encoding.UTF8.GetBytes("12345678");
+var desEncrypted = DES.Create().Encrypt(data, desKey);
+
+// 3DES ����
+var tripleDesKey = Encoding.UTF8.GetBytes("123456789012345678901234");
+var tripleDesEncrypted = TripleDES.Create().Encrypt(data, tripleDesKey);
+```
+
+#### ��ʽ����
+
+```csharp
+public static SymmetricAlgorithm Encrypt(this SymmetricAlgorithm sa, Stream instream, Stream outstream)
+public static SymmetricAlgorithm Decrypt(this SymmetricAlgorithm sa, Stream instream, Stream outstream)
+```
+
+�����������м���/���ܣ��ʺϴ������ļ���
+
+**ʾ��**��
+```csharp
+using var input = File.OpenRead("large-file.bin");
+using var output = File.Create("large-file.enc");
+
+var aes = Aes.Create();
+aes.Key = key;
+aes.IV = iv;
+aes.Encrypt(input, output);
+```
+
+#### Transform
+
+```csharp
+public static Byte[] Transform(this ICryptoTransform transform, Byte[] data)
+```
+
+ʹ�� `ICryptoTransform` ֱ��ת�����ݡ�
+
+**ʾ��**��
+```csharp
+var aes = Aes.Create();
+aes.Key = key;
+aes.IV = iv;
+
+using var encryptor = aes.CreateEncryptor();
+var encrypted = encryptor.Transform(data);
+
+using var decryptor = aes.CreateDecryptor();
+var decrypted = decryptor.Transform(encrypted);
+```
+
+#### RC4
+
+```csharp
+public static Byte[] RC4(this Byte[] data, Byte[] pass)
+```
+
+RC4 ��������ܡ�RC4 ���ܺͽ���ʹ����ͬ�ķ�����
+
+**ʾ��**��
+```csharp
+var data = Encoding.UTF8.GetBytes("Hello");
+var key = Encoding.UTF8.GetBytes("secret");
+
+// ����
+var encrypted = data.RC4(key);
+
+// ���ܣ�ͬ���ķ�����
+var decrypted = encrypted.RC4(key);
+```
+
+## ������ȫ��
+
+### RSAHelper
+
+RSA �ǶԳƼ��ܸ����ࡣ
+
+```csharp
+using NewLife.Security;
+
+// ������Կ��
+var (publicKey, privateKey) = RSAHelper.GenerateKey(2048);
+
+// ����
+var encrypted = RSAHelper.Encrypt(data, publicKey);
+
+// ����
+var decrypted = RSAHelper.Decrypt(encrypted, privateKey);
+
+// ǩ��
+var signature = RSAHelper.Sign(data, privateKey, "SHA256");
+
+// ��ǩ
+var isValid = RSAHelper.Verify(data, signature, publicKey, "SHA256");
+```
+
+### DSAHelper
+
+DSA ����ǩ�������ࡣ
+
+```csharp
+using NewLife.Security;
+
+// ǩ��
+var signature = DSAHelper.Sign(data, privateKey);
+
+// ��ǩ
+var isValid = DSAHelper.Verify(data, signature, publicKey);
+```
+
+### Rand
+
+�������������
+
+```csharp
+using NewLife.Security;
+
+// ��������ֽ�
+var bytes = Rand.NextBytes(16);
+
+// �����������
+var num = Rand.Next(1, 100);
+
+// ��������ַ���
+var str = Rand.NextString(16); // �������ֺ���ĸ
+var strWithSpecial = Rand.NextString(16, true); // ���������ַ�
+```
+
+## ʹ�ó���
+
+### 1. �����ϣ�洢
+
+```csharp
+public class PasswordHelper
+{
+ public String HashPassword(String password, String salt)
+ {
+ // ʹ�� SHA256 + ��ֵ
+ var data = Encoding.UTF8.GetBytes(password + salt);
+ return data.SHA256().ToHex();
+ }
+
+ public Boolean VerifyPassword(String password, String salt, String hash)
+ {
+ return HashPassword(password, salt).EqualIgnoreCase(hash);
+ }
+}
+```
+
+### 2. API ǩ����֤
+
+```csharp
+public class ApiSignature
+{
+ public String Sign(String data, String secret)
+ {
+ var key = Encoding.UTF8.GetBytes(secret);
+ var content = Encoding.UTF8.GetBytes(data);
+ return content.SHA256(key).ToHex();
+ }
+
+ public Boolean Verify(String data, String signature, String secret)
+ {
+ return Sign(data, secret).EqualIgnoreCase(signature);
+ }
+}
+```
+
+### 3. ���ݼ��ܴ���
+
+```csharp
+public class SecureTransport
+{
+ private readonly Byte[] _key;
+
+ public SecureTransport(String password)
+ {
+ // ʹ������������Կ
+ _key = password.MD5().ToHex().GetBytes()[..16];
+ }
+
+ public Byte[] Encrypt(Byte[] data)
+ {
+ return Aes.Create().Encrypt(data, _key);
+ }
+
+ public Byte[] Decrypt(Byte[] data)
+ {
+ return Aes.Create().Decrypt(data, _key);
+ }
+}
+```
+
+### 4. �ļ�������У��
+
+```csharp
+public class FileVerifier
+{
+ public String ComputeHash(String filePath)
+ {
+ return filePath.AsFile().MD5().ToHex();
+ }
+
+ public Boolean Verify(String filePath, String expectedHash)
+ {
+ var actualHash = ComputeHash(filePath);
+ return actualHash.EqualIgnoreCase(expectedHash);
+ }
+}
+```
+
+## ���ʵ��
+
+### 1. ѡ����ʵ��㷨
+
+```csharp
+// �����ϣ��ʹ�� SHA256 ���ǿ���㷨
+var passwordHash = (password + salt).GetBytes().SHA256().ToHex();
+
+// ���������ԣ�MD5 �㹻����
+var checksum = data.MD5().ToHex();
+
+// �����ܹ�ϣ����ʹ�� Murmur128
+var hash = data.Murmur128();
+```
+
+### 2. ע�����ģʽ������
+
+```csharp
+// �� Java ϵͳ����ʱʹ�� ECB ģʽ
+var encrypted = Aes.Create().Encrypt(data, key, CipherMode.ECB);
+
+// ��ȫ��Ҫ���ʱʹ�� CBC ģʽ��Ĭ�ϣ�
+var encrypted = Aes.Create().Encrypt(data, key, CipherMode.CBC);
+```
+
+### 3. ��Կ����
+
+```csharp
+// ��ҪӲ������Կ
+var key = Environment.GetEnvironmentVariable("ENCRYPTION_KEY")?.ToHex();
+
+// ʹ�ð�ȫ�������������Կ
+var randomKey = Rand.NextBytes(32);
+```
+
+## �㷨�Ա�
+
+| �㷨 | ������� | �ٶ� | ��ȫ�� | ��; |
+|------|---------|------|--------|------|
+| MD5 | 16�ֽ� | �ܿ� | �� | У��͡��ǰ�ȫ��ϣ |
+| SHA1 | 20�ֽ� | �� | �� | ���ݾ�ϵͳ |
+| SHA256 | 32�ֽ� | �� | �� | ͨ�ð�ȫ��ϣ |
+| SHA512 | 64�ֽ� | ���� | �ܸ� | �߰�ȫҪ�� |
+| CRC32 | 4�ֽ� | ���� | �� | ����У�� |
+| Murmur128 | 16�ֽ� | ���� | �� | ��ϣ�� |
+
+## �������
+
+- [����ת�� Utility](utility-����ת��Utility.md)
+- [������չ IOHelper](io_helper-������չIOHelper.md)
+- [Webͨ������ JwtBuilder](jwt-Webͨ������JwtBuilder.md)
+- [�ֲ�ʽ����ǩ������ TokenProvider](token_provider-�ֲ�ʽ����ǩ������TokenProvider.md)
diff --git "a/Doc/\345\257\271\350\261\241\345\256\271\345\231\250ObjectContainer.md" "b/Doc/\345\257\271\350\261\241\345\256\271\345\231\250ObjectContainer.md"
new file mode 100644
index 0000000..1c1f594
--- /dev/null
+++ "b/Doc/\345\257\271\350\261\241\345\256\271\345\231\250ObjectContainer.md"
@@ -0,0 +1,528 @@
+# �������� ObjectContainer
+
+## ����
+
+`ObjectContainer` �� NewLife.Core �е�����������ע�루DI���������ṩ��ǿ��� IoC ���ܡ�֧�ֵ�����˲̬�������������������ڣ����� `IServiceProvider` �ӿڣ�����Ϊ ASP.NET Core ���� DI �IJ���������
+
+**�����ռ�**��`NewLife.Model`
+**�ĵ���ַ**��https://newlifex.com/core/object_container
+
+## ��������
+
+- **������**�����ⲿ���������뾫��
+- **������������**��������Singleton����˲̬��Transient����������Scoped��
+- **���캯��ע��**���Զ��������캯������
+- **����ί��**��֧���Զ���ʵ��������
+- **ȫ������**���ṩ `ObjectContainer.Current` ȫ�ַ���
+- **������**��ʵ�� `IServiceProvider` �ӿڣ������ DI ������
+
+## ���ٿ�ʼ
+
+```csharp
+using NewLife.Model;
+
+// ��ȡȫ������
+var ioc = ObjectContainer.Current;
+
+// ע�����
+ioc.AddSingleton<ILogger, ConsoleLogger>(); // ����
+ioc.AddTransient<IUserService, UserService>(); // ˲̬
+ioc.AddScoped<IDbContext, MyDbContext>(); // ������
+
+// ���������ṩ��
+var provider = ioc.BuildServiceProvider();
+
+// ��������
+var logger = provider.GetService<ILogger>();
+var userService = provider.GetRequiredService<IUserService>();
+```
+
+## API �ο�
+
+### ȫ�ַ���
+
+#### Current
+
+```csharp
+public static IObjectContainer Current { get; set; }
+```
+
+ȫ��Ĭ������ʵ����Ӧ������ʱ�Զ�������
+
+**ʾ��**��
+```csharp
+// ���κεط�����ȫ������
+var container = ObjectContainer.Current;
+container.AddSingleton<IMyService, MyService>();
+```
+
+#### Provider
+
+```csharp
+public static IServiceProvider Provider { get; set; }
+```
+
+ȫ��Ĭ�Ϸ����ṩ�ߡ��� `Current` ����������
+
+**ʾ��**��
+```csharp
+// ֱ��ͨ��ȫ���ṩ�߽�������
+var service = ObjectContainer.Provider.GetService<IMyService>();
+```
+
+### ����ע��
+
+#### AddSingleton��������
+
+```csharp
+// ע������ӳ��
+IObjectContainer AddSingleton<TService, TImplementation>()
+IObjectContainer AddSingleton(Type serviceType, Type implementationType)
+
+// ע��ʵ��
+IObjectContainer AddSingleton<TService>(TService instance)
+IObjectContainer AddSingleton(Type serviceType, Object instance)
+
+// ע�Ṥ��
+IObjectContainer AddSingleton<TService>(Func<IServiceProvider, TService> factory)
+IObjectContainer AddSingleton(Type serviceType, Func<IServiceProvider, Object> factory)
+```
+
+ע�ᵥ����������Ӧ������������ֻ����һ��ʵ����
+
+**ʾ��**��
+```csharp
+var ioc = ObjectContainer.Current;
+
+// ����ӳ��
+ioc.AddSingleton<ILogger, FileLogger>();
+
+// ֱ��ע��ʵ��
+var config = new AppConfig { Debug = true };
+ioc.AddSingleton<AppConfig>(config);
+
+// ����ί�У��ӳٴ�����
+ioc.AddSingleton<IDbConnection>(sp =>
+{
+ var config = sp.GetService<AppConfig>();
+ return new SqlConnection(config.ConnectionString);
+});
+```
+
+#### AddTransient��˲̬��
+
+```csharp
+IObjectContainer AddTransient<TService, TImplementation>()
+IObjectContainer AddTransient<TService>()
+IObjectContainer AddTransient(Type serviceType, Type implementationType)
+IObjectContainer AddTransient(Type serviceType, Func<IServiceProvider, Object> factory)
+```
+
+ע��˲̬����ÿ����������ʵ����
+
+**ʾ��**��
+```csharp
+// ÿ�ν�����������ʵ��
+ioc.AddTransient<IUserService, UserService>();
+
+// ����ע��
+ioc.AddTransient<OrderProcessor>();
+
+// ������
+ioc.AddTransient<HttpClient>(sp => new HttpClient
+{
+ BaseAddress = new Uri("https://api.example.com"),
+ Timeout = TimeSpan.FromSeconds(30)
+});
+```
+
+#### AddScoped��������
+
+```csharp
+IObjectContainer AddScoped<TService, TImplementation>()
+IObjectContainer AddScoped<TService>()
+IObjectContainer AddScoped(Type serviceType, Type implementationType)
+IObjectContainer AddScoped(Type serviceType, Func<IServiceProvider, Object> factory)
+```
+
+ע�������������ͬһ�������ڹ���ʵ����
+
+**ʾ��**��
+```csharp
+// ͬһ�����ڹ���
+ioc.AddScoped<IDbContext, AppDbContext>();
+
+// ������
+ioc.AddScoped<IUnitOfWork>(sp =>
+{
+ var context = sp.GetService<IDbContext>();
+ return new UnitOfWork(context);
+});
+```
+
+#### TryAdd ϵ��
+
+```csharp
+IObjectContainer TryAddSingleton<TService, TImplementation>()
+IObjectContainer TryAddTransient<TService, TImplementation>()
+IObjectContainer TryAddScoped<TService, TImplementation>()
+```
+
+�������ӷ�������Ѵ�����ͬ�������������ӡ�
+
+**ʾ��**��
+```csharp
+// ����δע��ʱ����
+ioc.TryAddSingleton<ILogger, ConsoleLogger>();
+
+// �����������Ӳ�����Ч
+ioc.TryAddSingleton<ILogger, FileLogger>(); // ������
+
+// �� Add �����ӣ��������ʵ�֣�
+ioc.AddSingleton<ILogger, FileLogger>(); // ������
+```
+
+### �������
+
+#### BuildServiceProvider
+
+```csharp
+public IServiceProvider BuildServiceProvider()
+```
+
+���������������ṩ�ߡ�
+
+**ʾ��**��
+```csharp
+var ioc = ObjectContainer.Current;
+ioc.AddSingleton<IMyService, MyService>();
+
+var provider = ioc.BuildServiceProvider();
+```
+
+#### GetService
+
+```csharp
+// IServiceProvider �ӿڷ���
+Object? GetService(Type serviceType)
+```
+
+��ȡ����ʵ����δ�ҵ����� null��
+
+**ʾ��**��
+```csharp
+var service = provider.GetService(typeof(IMyService));
+if (service != null)
+{
+ // ʹ�÷���
+}
+```
+
+#### ��չ����
+
+```csharp
+// ���ͻ�ȡ
+T? GetService<T>(this IServiceProvider provider)
+
+// �����ȡ��δ�ҵ����쳣��
+T GetRequiredService<T>(this IServiceProvider provider)
+
+// ��ȡ����ʵ��
+IEnumerable<T> GetServices<T>(this IServiceProvider provider)
+```
+
+**ʾ��**��
+```csharp
+// ���ͻ�ȡ
+var logger = provider.GetService<ILogger>();
+
+// �������δע������쳣��
+var config = provider.GetRequiredService<AppConfig>();
+
+// ��ȡ����ʵ��
+var handlers = provider.GetServices<IMessageHandler>();
+foreach (var handler in handlers)
+{
+ handler.Handle(message);
+}
+```
+
+## �����������
+
+### Singleton��������
+
+```csharp
+ioc.AddSingleton<IMyService, MyService>();
+```
+
+- **����ʱ��**���״�����ʱ����
+- **��������**������Ӧ����������
+- **���ó���**�����á���־���������״̬��ȫ�ֹ����ķ���
+
+### Transient��˲̬��
+
+```csharp
+ioc.AddTransient<IMyService, MyService>();
+```
+
+- **����ʱ��**��ÿ������ʱ����
+- **��������**��ʹ���꼴�ɱ� GC
+- **���ó���**������������״̬�ķ���
+
+### Scoped��������
+
+```csharp
+ioc.AddScoped<IMyService, MyService>();
+```
+
+- **����ʱ��**�����������״�����ʱ����
+- **��������**�����������ʱ�ͷ�
+- **���ó���**��Web �������ݿ������ĵ�
+
+## ���캯��ע��
+
+ObjectContainer ֧���Զ����캯��ע�룺
+
+```csharp
+public interface ILogger { }
+public class ConsoleLogger : ILogger { }
+
+public interface IRepository { }
+public class UserRepository : IRepository
+{
+ public ILogger Logger { get; }
+
+ // ���캯��ע��
+ public UserRepository(ILogger logger)
+ {
+ Logger = logger;
+ }
+}
+
+// ע��
+ioc.AddSingleton<ILogger, ConsoleLogger>();
+ioc.AddTransient<IRepository, UserRepository>();
+
+// ����ʱ�Զ�ע�� ILogger
+var repo = provider.GetService<IRepository>();
+// repo.Logger �ѱ�ע��
+```
+
+### ���캯��ѡ�����
+
+1. ѡ��������Ĺ������캯��
+2. ������˳���������
+3. ��������ʹ��Ĭ��ֵ��int=0, string=null �ȣ�
+4. ���в������ܽ���ʱ��ʹ�øù��캯��
+5. ������ʱ�׳� `InvalidOperationException`
+
+## ʹ�ó���
+
+### 1. ����̨Ӧ��
+
+```csharp
+class Program
+{
+ static void Main()
+ {
+ // ��������
+ var ioc = ObjectContainer.Current;
+ ioc.AddSingleton<ILogger, ConsoleLogger>();
+ ioc.AddSingleton<AppConfig>();
+ ioc.AddTransient<IUserService, UserService>();
+
+ // �����ṩ��
+ var provider = ioc.BuildServiceProvider();
+
+ // ����Ӧ��
+ var app = provider.GetRequiredService<IUserService>();
+ app.Run();
+ }
+}
+```
+
+### 2. �� ASP.NET Core ����
+
+```csharp
+public class Startup
+{
+ public void ConfigureServices(IServiceCollection services)
+ {
+ // ���� NewLife ������ע��
+ var ioc = ObjectContainer.Current;
+ ioc.AddSingleton<IMyService, MyService>();
+
+ // ���Ƶ� ASP.NET Core ����
+ foreach (var item in ioc.Services)
+ {
+ // ת�������ӵ� services
+ }
+
+ // ����ֱ���滻����
+ // services.AddSingleton(ObjectContainer.Provider);
+ }
+}
+```
+
+### 3. ���ϵͳ
+
+```csharp
+public class PluginLoader
+{
+ private readonly IObjectContainer _container;
+
+ public PluginLoader()
+ {
+ _container = new ObjectContainer();
+ }
+
+ public void LoadPlugins(String pluginPath)
+ {
+ var assemblies = Directory.GetFiles(pluginPath, "*.dll")
+ .Select(Assembly.LoadFrom);
+
+ foreach (var assembly in assemblies)
+ {
+ var pluginTypes = assembly.GetTypes()
+ .Where(t => typeof(IPlugin).IsAssignableFrom(t) && !t.IsAbstract);
+
+ foreach (var type in pluginTypes)
+ {
+ _container.AddTransient(typeof(IPlugin), type);
+ }
+ }
+ }
+
+ public IEnumerable<IPlugin> GetPlugins()
+ {
+ var provider = _container.BuildServiceProvider();
+ return provider.GetServices<IPlugin>();
+ }
+}
+```
+
+### 4. ��Ԫ����
+
+```csharp
+[TestClass]
+public class UserServiceTests
+{
+ private IServiceProvider _provider;
+
+ [TestInitialize]
+ public void Setup()
+ {
+ var ioc = new ObjectContainer();
+
+ // ע�� Mock ����
+ ioc.AddSingleton<ILogger>(new MockLogger());
+ ioc.AddSingleton<IRepository>(new MockRepository());
+ ioc.AddTransient<IUserService, UserService>();
+
+ _provider = ioc.BuildServiceProvider();
+ }
+
+ [TestMethod]
+ public void TestCreateUser()
+ {
+ var service = _provider.GetRequiredService<IUserService>();
+ var result = service.CreateUser("test");
+ Assert.IsNotNull(result);
+ }
+}
+```
+
+## ���ʵ��
+
+### 1. ��Ӧ������ʱ���ע��
+
+```csharp
+// �Ƽ�������ʱ����ע��
+public static void Main()
+{
+ var ioc = ObjectContainer.Current;
+ ConfigureServices(ioc);
+
+ var provider = ioc.BuildServiceProvider();
+ // ����Ӧ��...
+}
+
+static void ConfigureServices(IObjectContainer ioc)
+{
+ ioc.AddSingleton<ILogger, FileLogger>();
+ ioc.AddTransient<IUserService, UserService>();
+ // ...
+}
+```
+
+### 2. �������λ��ģʽ
+
+```csharp
+// ���Ƽ�������λ��
+public class BadService
+{
+ public void DoWork()
+ {
+ var logger = ObjectContainer.Provider.GetService<ILogger>();
+ logger.Log("Working...");
+ }
+}
+
+// �Ƽ������캯��ע��
+public class GoodService
+{
+ private readonly ILogger _logger;
+
+ public GoodService(ILogger logger)
+ {
+ _logger = logger;
+ }
+
+ public void DoWork()
+ {
+ _logger.Log("Working...");
+ }
+}
+```
+
+### 3. ����ѡ����������
+
+```csharp
+// ���á���־�� �� ����
+ioc.AddSingleton<AppConfig>();
+ioc.AddSingleton<ILogger, FileLogger>();
+
+// ���ݿ������� �� ������Web����˲̬������̨��
+ioc.AddScoped<IDbContext, AppDbContext>(); // Web
+ioc.AddTransient<IDbContext, AppDbContext>(); // ����̨
+
+// ���������� �� ˲̬
+ioc.AddTransient<IValidator, UserValidator>();
+```
+
+### 4. ʹ�ýӿڶ��Ǿ�������
+
+```csharp
+// �Ƽ�������ӿ�
+ioc.AddSingleton<IUserService, UserService>();
+
+// ���Ƽ���ֱ��ע��������ͣ����Բ��Ժ��滻��
+ioc.AddSingleton<UserService>();
+```
+
+## �� Microsoft.Extensions.DependencyInjection �Ա�
+
+| ���� | ObjectContainer | MS DI |
+|------|-----------------|-------|
+| ����С | ��С�����ã� | ��Ҫ����� |
+| �������� | ֧�� | ֧�� |
+| ���캯��ע�� | ֧�� | ֧�� |
+| ����ע�� | ��֧�� | ��֧�� |
+| ����ע�� | ����֧�� | ����֧�� |
+| װ����ģʽ | ��֧�� | ֧�� |
+| ��֤ | �� | ֧�� |
+
+## �������
+
+- [������Ӧ������ Host](host-������Ӧ������Host.md)
+- [������ IPlugin](plugin-������IPlugin.md)
diff --git "a/Doc/\345\257\271\350\261\241\346\261\240Pool.md" "b/Doc/\345\257\271\350\261\241\346\261\240Pool.md"
new file mode 100644
index 0000000..70af14d
--- /dev/null
+++ "b/Doc/\345\257\271\350\261\241\346\261\240Pool.md"
@@ -0,0 +1,393 @@
+# ����� Pool
+
+## ����
+
+`Pool<T>` �� NewLife.Core �е������������ʵ�֣���������������ƣ�ͨ�� CAS ����ʵ�ָ����ܵĶ����á�����ؿ�����������Ƶ���������ٶ�������� GC ѹ�����ر��ʺϸ�Ƶ������
+
+**�����ռ�**��`NewLife.Collections`
+**�ĵ���ַ**��https://newlifex.com/core/object_pool
+
+## ��������
+
+- **�������**��ʹ�� `Interlocked.CompareExchange` ʵ����������
+- **�ȵ��λ**������ά�����ȶ������������ٶ�
+- **GC �Ѻ�**��֧�ֶ��� GC ʱ�Զ�����
+- **������**��O(N) ɨ�裬�ṹ��������ñ���������
+- **���ó�**���ṩ `StringBuilder`��`MemoryStream` �ȳ��ó�
+
+## ���ٿ�ʼ
+
+### ����ʹ��
+
+```csharp
+using NewLife.Collections;
+
+// ���������
+var pool = new Pool<MyObject>();
+
+// ��ȡ����
+var obj = pool.Get();
+
+try
+{
+ // ʹ�ö���...
+ obj.DoSomething();
+}
+finally
+{
+ // �黹����
+ pool.Return(obj);
+}
+```
+
+### ʹ������ StringBuilder ��
+
+```csharp
+using NewLife.Collections;
+
+// �ӳ��л�ȡ StringBuilder
+var sb = Pool.StringBuilder.Get();
+
+sb.Append("Hello ");
+sb.Append("World");
+
+// �黹����ȡ���
+var result = sb.Return(true); // ���� "Hello World"
+
+// ����Ҫ���ʱ
+sb.Return(false);
+```
+
+## API �ο�
+
+### IPool<T> �ӿ�
+
+```csharp
+public interface IPool<T>
+{
+ /// <summary>����ش�С</summary>
+ Int32 Max { get; set; }
+
+ /// <summary>��ȡ����</summary>
+ T Get();
+
+ /// <summary>�黹����</summary>
+ Boolean Return(T value);
+
+ /// <summary>��ն����</summary>
+ Int32 Clear();
+}
+```
+
+### Pool<T> ��
+
+```csharp
+public class Pool<T> : IPool<T> where T : class
+{
+ /// <summary>����ش�С��Ĭ�� CPU*2����С8</summary>
+ public Int32 Max { get; set; }
+
+ /// <summary>��ȡ���ؿ�ʱ������ʵ��</summary>
+ public virtual T Get();
+
+ /// <summary>�黹����</summary>
+ public virtual Boolean Return(T value);
+
+ /// <summary>��ն����</summary>
+ public virtual Int32 Clear();
+
+ /// <summary>�����������</summary>
+ protected virtual T? OnCreate();
+}
+```
+
+#### ���캯��
+
+```csharp
+// Ĭ�Ϲ��죬��СΪ CPU*2
+var pool = new Pool<MyObject>();
+
+// ָ����С
+var pool = new Pool<MyObject>(100);
+
+// ���� GC ������protected��
+protected Pool(Int32 max, Boolean useGcClear)
+```
+
+## ���ö����
+
+### StringBuilder ��
+
+```csharp
+public static class Pool
+{
+ /// <summary>�ַ�����������</summary>
+ public static IPool<StringBuilder> StringBuilder { get; set; }
+}
+```
+
+**ʹ��ʾ��**��
+```csharp
+var sb = Pool.StringBuilder.Get();
+sb.Append("Name: ");
+sb.Append(name);
+sb.AppendLine();
+
+// ��ʽ1���黹����ȡ���
+var result = sb.Return(true);
+
+// ��ʽ2�����黹
+sb.Return(false);
+```
+
+### StringBuilderPool ��
+
+```csharp
+public class StringBuilderPool : Pool<StringBuilder>
+{
+ /// <summary>��ʼ������Ĭ��100</summary>
+ public Int32 InitialCapacity { get; set; }
+
+ /// <summary>�����������������أ�Ĭ��4K</summary>
+ public Int32 MaximumCapacity { get; set; }
+}
+```
+
+�黹ʱ�Զ�������ݣ�������������IJ�������С�
+
+## ʹ�ó���
+
+### 1. ��Ƶ������
+
+```csharp
+public class MessageProcessor
+{
+ private readonly Pool<Message> _pool = new();
+
+ public void Process(Byte[] data)
+ {
+ var msg = _pool.Get();
+ try
+ {
+ msg.Parse(data);
+ HandleMessage(msg);
+ }
+ finally
+ {
+ msg.Reset(); // ����״̬
+ _pool.Return(msg);
+ }
+ }
+}
+```
+
+### 2. ��������
+
+```csharp
+public class BufferPool : Pool<Byte[]>
+{
+ public Int32 BufferSize { get; set; } = 4096;
+
+ protected override Byte[] OnCreate() => new Byte[BufferSize];
+
+ public override Boolean Return(Byte[] value)
+ {
+ // ��С��ƥ�䲻���
+ if (value.Length != BufferSize) return false;
+
+ // �������
+ Array.Clear(value, 0, value.Length);
+
+ return base.Return(value);
+ }
+}
+
+// ʹ��
+var bufferPool = new BufferPool { BufferSize = 8192 };
+var buffer = bufferPool.Get();
+try
+{
+ var read = stream.Read(buffer, 0, buffer.Length);
+ // ��������...
+}
+finally
+{
+ bufferPool.Return(buffer);
+}
+```
+
+### 3. ���ݿ����ӳ�
+
+```csharp
+public class ConnectionPool : Pool<DbConnection>
+{
+ public String ConnectionString { get; set; }
+
+ protected override DbConnection OnCreate()
+ {
+ var conn = new MySqlConnection(ConnectionString);
+ conn.Open();
+ return conn;
+ }
+
+ public override Boolean Return(DbConnection value)
+ {
+ // �����ѶϿ������
+ if (value.State != ConnectionState.Open) return false;
+
+ return base.Return(value);
+ }
+}
+```
+
+### 4. ��ʱ����
+
+```csharp
+public class ListPool<T> : Pool<List<T>>
+{
+ public Int32 MaxCapacity { get; set; } = 1000;
+
+ protected override List<T> OnCreate() => new(16);
+
+ public override Boolean Return(List<T> value)
+ {
+ if (value.Capacity > MaxCapacity) return false;
+
+ value.Clear();
+ return base.Return(value);
+ }
+}
+
+// ʹ��
+var listPool = new ListPool<Int32>();
+var list = listPool.Get();
+try
+{
+ list.Add(1);
+ list.Add(2);
+ // ����...
+}
+finally
+{
+ listPool.Return(list);
+}
+```
+
+### 5. ��� using ģʽ
+
+```csharp
+public class PooledObject<T> : IDisposable where T : class
+{
+ private readonly IPool<T> _pool;
+ public T Value { get; }
+
+ public PooledObject(IPool<T> pool)
+ {
+ _pool = pool;
+ Value = pool.Get();
+ }
+
+ public void Dispose()
+ {
+ _pool.Return(Value);
+ }
+}
+
+// ʹ��
+using (var pooled = new PooledObject<StringBuilder>(Pool.StringBuilder))
+{
+ pooled.Value.Append("Hello");
+ var result = pooled.Value.ToString();
+}
+```
+
+## �Զ�������
+
+```csharp
+public class MyObjectPool : Pool<MyObject>
+{
+ public MyObjectPool() : base(100) { } // �ش�С100
+
+ protected override MyObject OnCreate()
+ {
+ // �Զ��崴����
+ return new MyObject
+ {
+ Id = Guid.NewGuid(),
+ CreateTime = DateTime.Now
+ };
+ }
+
+ public override Boolean Return(MyObject value)
+ {
+ // �黹ǰ���ö���
+ value.Reset();
+
+ // ��֤����״̬
+ if (!value.IsValid) return false;
+
+ return base.Return(value);
+ }
+}
+```
+
+## ������
+
+### 1. Ԥ�ȶ����
+
+```csharp
+var pool = new Pool<MyObject>(50);
+
+// Ԥ�ȣ�����һ������������
+for (var i = 0; i < 50; i++)
+{
+ var obj = new MyObject();
+ pool.Return(obj);
+}
+```
+
+### 2. �������ô�С
+
+```csharp
+// ���ݲ���������
+var pool = new Pool<MyObject>(Environment.ProcessorCount * 4);
+```
+
+### 3. ��������
+
+```csharp
+// ��������Ӱ�� GC������ʹ�� ArrayPool
+var buffer = ArrayPool<Byte>.Shared.Rent(1024 * 1024);
+try
+{
+ // ʹ�û�����
+}
+finally
+{
+ ArrayPool<Byte>.Shared.Return(buffer);
+}
+```
+
+## �� ArrayPool �Ա�
+
+| ���� | Pool<T> | ArrayPool<T> |
+|------|--------------|-------------------|
+| Ŀ������ | �������� | ���� |
+| �̰߳�ȫ | �ǣ�CAS�� | �� |
+| GC ���� | ��ѡ | �Զ� |
+| ��С���� | �̶� | ��̬ |
+| ���� | ������ | ������ |
+
+## ���ʵ��
+
+1. **��ʱ�黹**��ʹ�� try-finally ȷ������黹
+2. **����״̬**���黹ǰ���������ڲ�״̬
+3. **��֤����**���黹ʱ��������Ч��
+4. **������С**�����ݲ��������óش�С
+5. **����й©**��ȷ���쳣·��Ҳ�ܹ黹����
+
+## �������
+
+- [����ϵͳ ICache](cache-����ϵͳICache.md)
+- [�ַ�����չ StringHelper](string_helper-�ַ�����չStringHelper.md)
+- [������չ IOHelper](io_helper-������չIOHelper.md)
diff --git "a/Doc/\345\271\266\350\241\214\346\250\241\345\236\213Actor.md" "b/Doc/\345\271\266\350\241\214\346\250\241\345\236\213Actor.md"
new file mode 100644
index 0000000..4705529
--- /dev/null
+++ "b/Doc/\345\271\266\350\241\214\346\250\241\345\236\213Actor.md"
@@ -0,0 +1,487 @@
+# ����� Actor
+
+## ����
+
+`Actor` �� NewLife.Core �е��������б��ģ�ͣ�������Ϣ����ʵ���̰߳�ȫ���첽������ÿ�� Actor ӵ�ж�������Ϣ����ʹ����̣߳�ͨ����Ϣ���ݽ���ͨ�ţ������˴�ͳ�����ƴ����ĸ����Ժ��������⡣
+
+**�����ռ�**��`NewLife.Model`
+**�ĵ���ַ**��https://newlifex.com/core/actor
+
+## ��������
+
+- **�������**��ͨ����Ϣ���и���״̬��������ʽ����
+- **�����߳�**��ÿ�� Actor ʹ�ö����̴߳�����Ϣ����Ӱ���̳߳�
+- **��������**��֧������������Ϣ�����������
+- **��������**��֧��������Ϣ���������������ֹ�ڴ����
+- **�Զ�����**��������Ϣʱ�Զ����� Actor
+- **������**������ `ITracer` ֧����·��
+
+## ���ٿ�ʼ
+
+```csharp
+using NewLife.Model;
+
+// ���� Actor
+public class MyActor : Actor
+{
+ protected override Task ReceiveAsync(ActorContext context, CancellationToken cancellationToken)
+ {
+ var message = context.Message;
+ Console.WriteLine($"�յ���Ϣ: {message}");
+ return Task.CompletedTask;
+ }
+}
+
+// ʹ�� Actor
+var actor = new MyActor();
+
+// ������Ϣ
+actor.Tell("Hello");
+actor.Tell("World");
+
+// �ȴ�������ɺ�ֹͣ
+actor.Stop(5000);
+```
+
+## API �ο�
+
+### IActor �ӿ�
+
+```csharp
+public interface IActor
+{
+ /// <summary>������Ϣ�������ڲ�����</summary>
+ /// <param name="message">��Ϣ����</param>
+ /// <param name="sender">������Actor</param>
+ /// <returns>���ش�������Ϣ��</returns>
+ Int32 Tell(Object message, IActor? sender = null);
+}
+```
+
+### ActorContext ��
+
+```csharp
+public class ActorContext
+{
+ /// <summary>������</summary>
+ public IActor? Sender { get; set; }
+
+ /// <summary>��Ϣ</summary>
+ public Object? Message { get; set; }
+}
+```
+
+### Actor ����
+
+#### ����
+
+```csharp
+/// <summary>����</summary>
+public String Name { get; set; }
+
+/// <summary>�Ƿ�����</summary>
+public Boolean Active { get; }
+
+/// <summary>�������������ɶѻ�����Ϣ����Ĭ��Int32.MaxValue</summary>
+public Int32 BoundedCapacity { get; set; }
+
+/// <summary>����С��ÿ�δ�����Ϣ����Ĭ��1</summary>
+public Int32 BatchSize { get; set; }
+
+/// <summary>�Ƿ�ʱ�����С�Ĭ��true��ʹ�ö����߳�</summary>
+public Boolean LongRunning { get; set; }
+
+/// <summary>��ǰ���г���</summary>
+public Int32 QueueLength { get; }
+
+/// <summary>��������</summary>
+public ITracer? Tracer { get; set; }
+```
+
+#### Tell - ������Ϣ
+
+```csharp
+public virtual Int32 Tell(Object message, IActor? sender = null)
+```
+
+�� Actor ������Ϣ����� Actor δ���������Զ�������
+
+**����**��
+- `message`����Ϣ����������������
+- `sender`�������� Actor�����ڻظ���Ϣ
+
+**����ֵ**����ǰ����������Ϣ��
+
+**ʾ��**��
+```csharp
+var actor = new MyActor();
+
+// ���ͼ���Ϣ
+actor.Tell("Hello");
+
+// �����Ӷ���
+actor.Tell(new { Id = 1, Name = "Test" });
+
+// ��������
+actor.Tell("Ping", senderActor);
+```
+
+#### Start - ���� Actor
+
+```csharp
+public virtual Task? Start()
+public virtual Task? Start(CancellationToken cancellationToken)
+```
+
+�ֶ����� Actor��ͨ������Ҫ�ֶ����ã�`Tell` ���Զ�������
+
+**ʾ��**��
+```csharp
+var actor = new MyActor();
+
+// �ֶ�����
+actor.Start();
+
+// ��ȡ����������
+using var cts = new CancellationTokenSource();
+actor.Start(cts.Token);
+```
+
+#### Stop - ֹͣ Actor
+
+```csharp
+public virtual Boolean Stop(Int32 msTimeout = 0)
+```
+
+ֹͣ Actor�����ٽ�������Ϣ��
+
+**����**��
+- `msTimeout`���ȴ���������0=���ȴ���-1=���ȴ�
+
+**����ֵ**���Ƿ��ڳ�ʱǰ���������Ϣ����
+
+**ʾ��**��
+```csharp
+// ����ֹͣ�����ȴ�
+actor.Stop(0);
+
+// �ȴ����5��
+var completed = actor.Stop(5000);
+if (!completed)
+ Console.WriteLine("����Ϣδ�������");
+
+// ���ȴ�
+actor.Stop(-1);
+```
+
+#### ReceiveAsync - ������Ϣ
+
+```csharp
+// ����������BatchSize=1��
+protected virtual Task ReceiveAsync(ActorContext context, CancellationToken cancellationToken)
+
+// ����������BatchSize>1��
+protected virtual Task ReceiveAsync(ActorContext[] contexts, CancellationToken cancellationToken)
+```
+
+������д�˷���ʵ����Ϣ��������
+
+## ʹ�ó���
+
+### 1. ��־�ռ���
+
+```csharp
+public class LogActor : Actor
+{
+ private readonly StreamWriter _writer;
+
+ public LogActor(String filePath)
+ {
+ Name = "LogActor";
+ BatchSize = 100; // �����
+ BoundedCapacity = 10000; // ���ƶ���
+
+ _writer = new StreamWriter(filePath, true) { AutoFlush = false };
+ }
+
+ protected override async Task ReceiveAsync(ActorContext[] contexts, CancellationToken cancellationToken)
+ {
+ foreach (var ctx in contexts)
+ {
+ if (ctx.Message is String log)
+ {
+ await _writer.WriteLineAsync(log);
+ }
+ }
+ await _writer.FlushAsync();
+ }
+
+ protected override void Dispose(Boolean disposing)
+ {
+ base.Dispose(disposing);
+ _writer?.Dispose();
+ }
+}
+
+// ʹ��
+var logger = new LogActor("app.log");
+logger.Tell($"[{DateTime.Now:HH:mm:ss}] Ӧ������");
+logger.Tell($"[{DateTime.Now:HH:mm:ss}] ��������");
+```
+
+### 2. ��Ϣ������
+
+```csharp
+public class MessageProcessor : Actor
+{
+ private readonly IMessageHandler _handler;
+
+ public MessageProcessor(IMessageHandler handler)
+ {
+ Name = "MessageProcessor";
+ _handler = handler;
+ }
+
+ protected override async Task ReceiveAsync(ActorContext context, CancellationToken cancellationToken)
+ {
+ if (context.Message is Message msg)
+ {
+ try
+ {
+ await _handler.HandleAsync(msg, cancellationToken);
+
+ // �ظ�������
+ context.Sender?.Tell(new Ack { MessageId = msg.Id });
+ }
+ catch (Exception ex)
+ {
+ context.Sender?.Tell(new Error { MessageId = msg.Id, Exception = ex });
+ }
+ }
+ }
+}
+```
+
+### 3. ���ݾۺ���
+
+```csharp
+public class DataAggregator : Actor
+{
+ private readonly Dictionary<String, Int32> _counts = new();
+ private DateTime _lastFlush = DateTime.Now;
+
+ public DataAggregator()
+ {
+ Name = "DataAggregator";
+ BatchSize = 50;
+ }
+
+ protected override Task ReceiveAsync(ActorContext[] contexts, CancellationToken cancellationToken)
+ {
+ foreach (var ctx in contexts)
+ {
+ if (ctx.Message is String key)
+ {
+ _counts.TryGetValue(key, out var count);
+ _counts[key] = count + 1;
+ }
+ }
+
+ // ÿ�������һ��ͳ��
+ if ((DateTime.Now - _lastFlush).TotalMinutes >= 1)
+ {
+ foreach (var kv in _counts)
+ {
+ Console.WriteLine($"{kv.Key}: {kv.Value}");
+ }
+ _counts.Clear();
+ _lastFlush = DateTime.Now;
+ }
+
+ return Task.CompletedTask;
+ }
+}
+```
+
+### 4. Actor ֮��ͨ��
+
+```csharp
+public class PingActor : Actor
+{
+ protected override Task ReceiveAsync(ActorContext context, CancellationToken cancellationToken)
+ {
+ if (context.Message is String msg && msg == "Ping")
+ {
+ Console.WriteLine("PingActor �յ� Ping������ Pong");
+ context.Sender?.Tell("Pong", this);
+ }
+ return Task.CompletedTask;
+ }
+}
+
+public class PongActor : Actor
+{
+ protected override Task ReceiveAsync(ActorContext context, CancellationToken cancellationToken)
+ {
+ if (context.Message is String msg && msg == "Pong")
+ {
+ Console.WriteLine("PongActor �յ� Pong");
+ }
+ return Task.CompletedTask;
+ }
+}
+
+// ʹ��
+var ping = new PingActor();
+var pong = new PongActor();
+
+// pong ���� Ping �� ping��ping ��ظ� Pong
+ping.Tell("Ping", pong);
+```
+
+### 5. ����������
+
+```csharp
+public class RateLimitedActor : Actor
+{
+ private readonly SemaphoreSlim _semaphore;
+ private readonly Int32 _maxConcurrency;
+
+ public RateLimitedActor(Int32 maxConcurrency = 10)
+ {
+ _maxConcurrency = maxConcurrency;
+ _semaphore = new SemaphoreSlim(maxConcurrency);
+ BatchSize = maxConcurrency;
+ }
+
+ protected override async Task ReceiveAsync(ActorContext[] contexts, CancellationToken cancellationToken)
+ {
+ var tasks = new List<Task>();
+
+ foreach (var ctx in contexts)
+ {
+ await _semaphore.WaitAsync(cancellationToken);
+
+ tasks.Add(Task.Run(async () =>
+ {
+ try
+ {
+ await ProcessAsync(ctx.Message, cancellationToken);
+ }
+ finally
+ {
+ _semaphore.Release();
+ }
+ }, cancellationToken));
+ }
+
+ await Task.WhenAll(tasks);
+ }
+
+ private async Task ProcessAsync(Object? message, CancellationToken cancellationToken)
+ {
+ // ������
+ await Task.Delay(100, cancellationToken);
+ }
+}
+```
+
+## ���ʵ��
+
+### 1. ������������С
+
+```csharp
+// IO�ܼ��ͣ��ϴ�����
+var ioActor = new IoActor { BatchSize = 100 };
+
+// CPU�ܼ��ͣ���С����
+var cpuActor = new CpuActor { BatchSize = 10 };
+
+// ʵʱ��Ҫ��ߣ���������
+var realtimeActor = new RealtimeActor { BatchSize = 1 };
+```
+
+### 2. ���ö�������
+
+```csharp
+// ��ֹ�ڴ����
+var actor = new MyActor
+{
+ BoundedCapacity = 10000 // ���ѻ�1������Ϣ
+};
+
+// �������
+if (actor.QueueLength > 5000)
+{
+ Console.WriteLine("���棺��Ϣ��ѹ");
+}
+```
+
+### 3. ����ֹͣ
+
+```csharp
+// ֹͣ��������Ϣ���ȴ�������Ϣ�������
+var completed = actor.Stop(30_000); // ����30��
+
+if (!completed)
+{
+ Console.WriteLine($"�� {actor.QueueLength} ����Ϣδ����");
+}
+```
+
+### 4. �쳣����
+
+```csharp
+public class SafeActor : Actor
+{
+ protected override async Task ReceiveAsync(ActorContext context, CancellationToken cancellationToken)
+ {
+ try
+ {
+ await ProcessAsync(context.Message);
+ }
+ catch (Exception ex)
+ {
+ // ��¼��־�����׳��쳣
+ XTrace.WriteException(ex);
+
+ // ��ѡ�����͵����Ŷ���
+ DeadLetterActor?.Tell(new DeadLetter
+ {
+ Message = context.Message,
+ Exception = ex
+ });
+ }
+ }
+}
+```
+
+### 5. ������
+
+```csharp
+var actor = new MyActor
+{
+ Tracer = new DefaultTracer() // ��ʹ���dz���
+};
+
+// ����Ϣ���Զ���¼��
+// - actor:Start
+// - actor:Loop
+// - actor:Stop
+```
+
+## ����������ģ�ͶԱ�
+
+| ���� | Actor | Task/async | �� |
+|------|-------|------------|-----|
+| �̰߳�ȫ | ��Ȼ��ȫ | ��Ҫע�� | ��Ҫ��ʽ���� |
+| ��̸��Ӷ� | �е� | �� | �� |
+| ���ó��� | IO�ܼ� | ͨ�� | ����״̬ |
+| ��ѹ���� | ֧�� | ��֧�� | ��֧�� |
+| ��Ϣ˳�� | ��֤ | ����֤ | ������ |
+
+## �������
+
+- [����ʱ�� TimerX](timerx-����ʱ��TimerX.md)
+- [������Ӧ������ Host](host-������Ӧ������Host.md)
+- [��·�� ITracer](tracer-��·��ITracer.md)
diff --git "a/Doc/\346\213\274\351\237\263\345\272\223PinYin.md" "b/Doc/\346\213\274\351\237\263\345\272\223PinYin.md"
new file mode 100644
index 0000000..1df4fb2
--- /dev/null
+++ "b/Doc/\346\213\274\351\237\263\345\272\223PinYin.md"
@@ -0,0 +1,390 @@
+# ƴ���� PinYin
+
+## ����
+
+`PinYin` �� NewLife.Core �еĺ���ƴ��ת�������࣬�ṩ��Ч�ĺ���תƴ�����ܡ�֧�� GB2312 һ���Ͷ������֣��ܹ���ȡ���ֵ�ȫƴ��ƴ������ĸ���������������������뷨�ȳ�����
+
+**�����ռ�**��`NewLife.Common`
+**�ĵ���ַ**��https://newlifex.com/core/pinyin
+
+## ��������
+
+- **������**������ GB2312 �������λ���㷨��������ش����ֵ��ļ�
+- **ȫ����֧��**������ GB2312 һ�����֣�3755�����Ͷ������֣�3008����
+- **�������**��֧��ȫƴ������ĸ������ƴ���ȶ�����ʽ
+- **������**�����ⲿ���������㷨ʵ��
+- **�����**��֧��"����"�ȶ����ֵij�������
+
+## ���ٿ�ʼ
+
+```csharp
+using NewLife.Common;
+
+// ��ȡ����ƴ��
+var py = PinYin.Get('��'); // "Zhong"
+
+// ��ȡ�ַ���ȫƴ
+var fullPy = PinYin.Get("������"); // "XinShengMing"
+
+// ��ȡƴ������ĸ
+var first = PinYin.GetFirst("������"); // "XSM"
+
+// ��ȡƴ������
+var arr = PinYin.GetAll("���"); // ["Ni", "Hao"]
+```
+
+## API �ο�
+
+### Get������ƴ����
+
+```csharp
+public static String Get(Char ch)
+```
+
+��ȡ�������ֵ�ƴ����
+
+**����˵��**��
+- `ch`��Ҫת�����ַ�
+
+**����ֵ**��
+- ���ַ�������ĸ��д��ƴ������ "Zhong"��
+- �����ַ�����㡢�������ַ�ԭ������
+- ��ʶ��ĺ��ַ��ؿ��ַ���
+
+**ʾ��**��
+```csharp
+PinYin.Get('��') // "Zhong"
+PinYin.Get('��') // "Guo"
+PinYin.Get('A') // "A"
+PinYin.Get('��') // "��"
+PinYin.Get('��') // "��"
+```
+
+### Get���ַ���ȫƴ��
+
+```csharp
+public static String Get(String str)
+```
+
+��ȡ�ַ���������ƴ��������ƴ��ֱ�����ӡ�
+
+**ʾ��**��
+```csharp
+PinYin.Get("�й�") // "ZhongGuo"
+PinYin.Get("�������Ŷ�") // "XinShengMingTuanDui"
+PinYin.Get("Hello����") // "HelloShiJie"
+```
+
+### GetAll
+
+```csharp
+public static String[] GetAll(String str)
+```
+
+��ȡ�ַ�����ÿ���ַ���ƴ���������ַ������顣
+
+**�����**��
+- "����" �����Ϊ ["Chong", "Qing"]
+
+**ʾ��**��
+```csharp
+PinYin.GetAll("���") // ["Ni", "Hao"]
+PinYin.GetAll("����") // ["Chong", "Qing"]
+PinYin.GetAll("ABC") // ["A", "B", "C"]
+PinYin.GetAll("Hello") // ["H", "e", "l", "l", "o"]
+```
+
+### GetFirst��ƴ������ĸ��
+
+```csharp
+public static Char GetFirst(Char ch)
+public static String GetFirst(String str)
+```
+
+��ȡ���ֻ��ַ�����ƴ������ĸ��
+
+**ʾ��**��
+```csharp
+// ��������ĸ
+PinYin.GetFirst('��') // 'Z'
+PinYin.GetFirst('��') // 'G'
+PinYin.GetFirst('A') // 'A'
+
+// �ַ�������ĸ
+PinYin.GetFirst("������") // "XSM"
+PinYin.GetFirst("�й�") // "ZG"
+PinYin.GetFirst("Hello") // "Hello"
+```
+
+## ʹ�ó���
+
+### 1. ����ƥ��
+
+```csharp
+public class UserService
+{
+ /// <summary>����ƴ������ĸ�����û�</summary>
+ public List<User> SearchByPinyin(List<User> users, String keyword)
+ {
+ var upperKeyword = keyword.ToUpper();
+
+ return users.Where(u =>
+ {
+ // ȫ��ƥ��
+ if (u.Name.Contains(keyword, StringComparison.OrdinalIgnoreCase))
+ return true;
+
+ // ƴ������ĸƥ��
+ var firstLetters = PinYin.GetFirst(u.Name);
+ return firstLetters.Contains(upperKeyword, StringComparison.OrdinalIgnoreCase);
+
+ }).ToList();
+ }
+}
+
+// ʹ��ʾ��
+var users = new List<User>
+{
+ new User { Name = "����" },
+ new User { Name = "����" },
+ new User { Name = "����" }
+};
+
+var result = service.SearchByPinyin(users, "ZS"); // �ҵ� "����"
+var result2 = service.SearchByPinyin(users, "LS"); // �ҵ� "����"
+```
+
+### 2. ��ƴ������
+
+```csharp
+public class ProductSorter
+{
+ /// <summary>��ƴ��������Ʒ����</summary>
+ public List<Product> SortByPinyin(List<Product> products)
+ {
+ return products
+ .OrderBy(p => PinYin.Get(p.Name))
+ .ToList();
+ }
+}
+
+// ʹ��ʾ��
+var products = new List<Product>
+{
+ new Product { Name = "ƻ��" },
+ new Product { Name = "�㽶" },
+ new Product { Name = "����" }
+};
+
+var sorted = sorter.SortByPinyin(products);
+// ������������(ChengZi) -> ƻ��(PingGuo) -> �㽶(XiangJiao)
+```
+
+### 3. ����ƴ������
+
+```csharp
+public class ContactIndexer
+{
+ /// <summary>������ϵ��ƴ������</summary>
+ public Dictionary<Char, List<Contact>> BuildIndex(List<Contact> contacts)
+ {
+ var index = new Dictionary<Char, List<Contact>>();
+
+ foreach (var contact in contacts)
+ {
+ var firstLetter = PinYin.GetFirst(contact.Name[0]);
+
+ if (!index.ContainsKey(firstLetter))
+ index[firstLetter] = new List<Contact>();
+
+ index[firstLetter].Add(contact);
+ }
+
+ return index;
+ }
+}
+
+// ʹ��ʾ��
+var contacts = new List<Contact>
+{
+ new Contact { Name = "����" },
+ new Contact { Name = "����" },
+ new Contact { Name = "����" }
+};
+
+var index = indexer.BuildIndex(contacts);
+// index['Z'] = [����, ����]
+// index['L'] = [����]
+```
+
+### 4. ���뷨��ʾ
+
+```csharp
+public class InputSuggestion
+{
+ private readonly List<String> _words;
+
+ public InputSuggestion(List<String> words)
+ {
+ _words = words;
+ }
+
+ /// <summary>���������ȡ�����</summary>
+ public List<String> GetSuggestions(String input)
+ {
+ if (input.IsNullOrEmpty()) return new List<String>();
+
+ var upperInput = input.ToUpper();
+
+ return _words
+ .Where(w =>
+ {
+ // ֧������ĸƥ��
+ var first = PinYin.GetFirst(w);
+ if (first.StartsWith(upperInput, StringComparison.OrdinalIgnoreCase))
+ return true;
+
+ // ֧��ȫƴƥ��
+ var full = PinYin.Get(w);
+ return full.StartsWith(upperInput, StringComparison.OrdinalIgnoreCase);
+ })
+ .Take(10)
+ .ToList();
+ }
+}
+
+// ʹ��ʾ��
+var words = new List<String> { "������", "�����", "��������", "���տ���" };
+var suggester = new InputSuggestion(words);
+
+suggester.GetSuggestions("XS"); // ["������", "��������"]
+suggester.GetSuggestions("Xin"); // ["������", "�����", "��������"]
+```
+
+### 5. ���ݿ�洢�Ż�
+
+```csharp
+public class User
+{
+ public Int32 Id { get; set; }
+ public String Name { get; set; }
+
+ /// <summary>����ƴ��������������</summary>
+ public String NamePinyin { get; set; }
+
+ /// <summary>��������ĸ������������</summary>
+ public String NameFirst { get; set; }
+
+ /// <summary>����ǰ�Զ�����ƴ���ֶ�</summary>
+ public void BeforeSave()
+ {
+ NamePinyin = PinYin.Get(Name);
+ NameFirst = PinYin.GetFirst(Name);
+ }
+}
+
+// ���ݿ��ѯʱ������ƴ���ֶμ�������
+// SELECT * FROM Users WHERE NameFirst LIKE 'ZS%'
+// SELECT * FROM Users WHERE NamePinyin LIKE 'Zhang%'
+```
+
+## ����ϸ��
+
+### �������
+
+PinYin ����� GB2312 ����ʵ�֣�
+
+1. **һ������**���� 3755 ������ƴ��˳������
+2. **��������**���� 3008 ���������ױʻ�˳������
+3. **���⺺��**������ GB2312 ��Χ�ij��ú��ֵ�������
+
+### �㷨ԭ��
+
+```
+�ַ� �� GB2312���� �� ��λ�� �� ƴ��ӳ��
+```
+
+1. ������ת��Ϊ GB2312 �ֽ�
+2. ������λ�루���ֽ�����ټ�ƫ�ƣ�
+3. һ������ͨ������ӳ����ٶ�λƴ��
+4. ��������ͨ��������һ�ȡƴ��
+
+### �����ص�
+
+- **���ֵ����**���㷨ֱ�Ӽ��㣬����������
+- **O(1) ���Ӷ�**��һ������ͨ���ֿ��㷨���ٶ�λ
+- **�ڴ�ռ��С**�����洢ƴ����������
+
+## ����˵��
+
+### ������
+
+Ŀǰ��֧�ֶ������������жϣ�������ȡ���ö�����
+
+```csharp
+PinYin.Get('��') // "Zhong"������ "Chong"��
+PinYin.Get("����") // "ChongQing"���������
+PinYin.Get("��Ҫ") // "ZhongYao"�������ö�����
+```
+
+### ��Ƨ��
+
+���� GB2312 ��Χ����Ƨ�ֿ�����ת����
+
+```csharp
+PinYin.Get('?') // "?"����ʶ��ԭ�����أ�
+```
+
+### ������
+
+��֧�ַ�����ת������Ҫ��ת���壺
+
+```csharp
+PinYin.Get('��') // "��"����ʶ��
+PinYin.Get('��') // "Guo"������������
+```
+
+## ���ʵ��
+
+### 1. Ԥ����ƴ���ֶ�
+
+```csharp
+// �Ƽ������ʱԤ�ȼ���ƴ��
+user.NamePinyin = PinYin.Get(user.Name);
+user.NameFirst = PinYin.GetFirst(user.Name);
+db.Save(user);
+
+// ���Ƽ���ÿ�β�ѯʱʵʱ����
+var users = db.Users.Where(u => PinYin.GetFirst(u.Name) == "ZS");
+```
+
+### 2. �����������
+
+```csharp
+// �Ƽ���ͬʱ֧��ԭ�ĺ�ƴ������
+public List<User> Search(String keyword)
+{
+ return users.Where(u =>
+ u.Name.Contains(keyword) ||
+ u.NamePinyin.Contains(keyword.ToUpper()) ||
+ u.NameFirst.Contains(keyword.ToUpper())
+ ).ToList();
+}
+```
+
+### 3. ���泣��ת��
+
+```csharp
+// ���ڸ�Ƶת���Ĵʻ㣬�ɿ��ǻ���
+private static readonly ConcurrentDictionary<String, String> _cache = new();
+
+public static String GetCached(String str)
+{
+ return _cache.GetOrAdd(str, s => PinYin.Get(s));
+}
+```
+
+## �������
+
+- [�ַ�����չ StringHelper](string_helper-�ַ�����չStringHelper.md)
+- [����ת�� Utility](utility-����ת��Utility.md)
diff --git "a/Doc/\346\217\222\344\273\266\346\241\206\346\236\266IPlugin.md" "b/Doc/\346\217\222\344\273\266\346\241\206\346\236\266IPlugin.md"
new file mode 100644
index 0000000..f6f2de3
--- /dev/null
+++ "b/Doc/\346\217\222\344\273\266\346\241\206\346\236\266IPlugin.md"
@@ -0,0 +1,508 @@
+# ������ IPlugin
+
+## ����
+
+`IPlugin` �� NewLife.Core �е�ͨ�ò���ӿڣ���� `PluginManager` ��������������Կ��ٹ���һ����ͨ�õIJ��ϵͳ��֧�ֲ�����֡����ء���ʼ������Դ�ͷŵ������������ڹ�����
+
+**�����ռ�**��`NewLife.Model`
+**�ĵ���ַ**��https://newlifex.com/core/plugin
+
+## ��������
+
+- **�Զ�����**��ɨ������Զ����� `IPlugin` ʵ��
+- **����ʶ��**��ͨ�� `PluginAttribute` ��Dz����������
+- **����ע��**��֧�ִ� `IServiceProvider` ʵ�������
+- **��������**��֧�ֳ�ʼ�������ٻص�
+- **��������**�������صķ���˳���ͷ���Դ
+
+## ���ٿ�ʼ
+
+### ������
+
+```csharp
+using NewLife.Model;
+
+// ���ʵ��
+[Plugin("MyApp")] // ���֧�ֵ�����
+public class MyPlugin : IPlugin
+{
+ public Boolean Init(String? identity, IServiceProvider provider)
+ {
+ if (identity != "MyApp") return false; // ��Ŀ������
+
+ Console.WriteLine("MyPlugin ��ʼ���ɹ�");
+ return true;
+ }
+}
+```
+
+### ���ز��
+
+```csharp
+using NewLife.Model;
+
+// �������������
+var manager = new PluginManager
+{
+ Identity = "MyApp",
+ Provider = ObjectContainer.Provider
+};
+
+// ���ز���ʼ�����
+manager.Load();
+manager.Init();
+
+// ʹ�ò��
+foreach (var plugin in manager.Plugins)
+{
+ Console.WriteLine($"�Ѽ��ز��: {plugin.GetType().Name}");
+}
+
+// �ͷ���Դ
+manager.Dispose();
+```
+
+## API �ο�
+
+### IPlugin �ӿ�
+
+```csharp
+public interface IPlugin
+{
+ /// <summary>��ʼ��</summary>
+ /// <param name="identity">���������ʶ</param>
+ /// <param name="provider">�����ṩ��</param>
+ /// <returns>���س�ʼ���Ƿ�ɹ�</returns>
+ Boolean Init(String? identity, IServiceProvider provider);
+}
+```
+
+**����˵��**��
+- `identity`��������ʶ�����ڲ���ж��Ƿ�ΪĿ������
+- `provider`�������ṩ�ߣ����ڻ�ȡ��������
+
+**����ֵ**��
+- `true`����ʼ���ɹ��������ò��
+- `false`����Ŀ���������ʼ��ʧ�ܣ��Ƴ��ò��
+
+### PluginAttribute ����
+
+```csharp
+[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
+public class PluginAttribute : Attribute
+{
+ public String Identity { get; set; }
+}
+```
+
+���ڱ�Dz��֧�ֵ�������ʶ��
+
+**ʾ��**��
+```csharp
+// ֧�ֵ�������
+[Plugin("WebServer")]
+public class WebPlugin : IPlugin { }
+
+// ֧�ֶ������
+[Plugin("WebServer")]
+[Plugin("ApiServer")]
+public class MultiHostPlugin : IPlugin { }
+```
+
+### PluginManager ��
+
+#### ����
+
+```csharp
+/// <summary>������ʶ</summary>
+public String? Identity { get; set; }
+
+/// <summary>���������ṩ��</summary>
+public IServiceProvider? Provider { get; set; }
+
+/// <summary>�������</summary>
+public IPlugin[]? Plugins { get; set; }
+
+/// <summary>��־�ṩ��</summary>
+public ILog Log { get; set; }
+```
+
+#### Load - ���ز��
+
+```csharp
+public void Load()
+```
+
+ɨ�����г�������ʵ�� `IPlugin` �ӿڵ����͡�
+
+**���ع���**��
+1. ɨ�������Ѽ��صij���
+2. ����ʵ�� `IPlugin` �ķdz�����
+3. ��� `PluginAttribute`�����˷ǵ�ǰ�����IJ��
+4. ͨ�������ṩ����ʵ����
+
+#### Init - ��ʼ�����
+
+```csharp
+public void Init()
+```
+
+���ε���ÿ������� `Init` �������Ƴ���ʼ��ʧ�ܵIJ����
+
+#### LoadPlugins - ��ȡ�������
+
+```csharp
+public IEnumerable<Type> LoadPlugins()
+```
+
+����ȡ������ͣ���ʵ��������������Ҫ�Զ���ʵ�������ij�����
+
+## �����������
+
+```
+1. �������� PluginManager
+2. ���� Load() - ���ֲ�ʵ�������
+3. ���� Init() - ��ʼ�����
+4. ���������...
+5. ���� Dispose() - �������ٲ��
+```
+
+### ��������ʾ��
+
+```csharp
+public class LifecyclePlugin : IPlugin, IDisposable
+{
+ private ILogger? _logger;
+
+ // ���캯�����������ز��ʱ����
+ public LifecyclePlugin()
+ {
+ Console.WriteLine("1. ���캯��������");
+ }
+
+ // ��ʼ�������������������
+ public Boolean Init(String? identity, IServiceProvider provider)
+ {
+ Console.WriteLine("2. Init ������");
+
+ // ��ȡ����
+ _logger = provider.GetService<ILogger>();
+ _logger?.Info("�����ʼ��");
+
+ return true;
+ }
+
+ // ���٣������ͷ�ʱ����
+ public void Dispose()
+ {
+ Console.WriteLine("3. Dispose ������");
+ _logger?.Info("�������");
+ }
+}
+```
+
+## ʹ�ó���
+
+### 1. ������չ���
+
+```csharp
+// ������չ��ӿ�
+public interface IDataProcessor
+{
+ String Name { get; }
+ void Process(Object data);
+}
+
+// ���ʵ��
+[Plugin("DataPipeline")]
+public class JsonProcessor : IPlugin, IDataProcessor
+{
+ public String Name => "JSON������";
+
+ public Boolean Init(String? identity, IServiceProvider provider)
+ {
+ return identity == "DataPipeline";
+ }
+
+ public void Process(Object data)
+ {
+ var json = data.ToJson();
+ Console.WriteLine($"����JSON: {json}");
+ }
+}
+
+// ����ʹ��
+var manager = new PluginManager { Identity = "DataPipeline" };
+manager.Load();
+manager.Init();
+
+foreach (var plugin in manager.Plugins.OfType<IDataProcessor>())
+{
+ plugin.Process(myData);
+}
+```
+
+### 2. �¼��������
+
+```csharp
+public interface IEventListener
+{
+ void OnEvent(String eventName, Object? args);
+}
+
+[Plugin("EventSystem")]
+public class LoggingPlugin : IPlugin, IEventListener
+{
+ private ILog? _log;
+
+ public Boolean Init(String? identity, IServiceProvider provider)
+ {
+ _log = provider.GetService<ILog>();
+ return identity == "EventSystem";
+ }
+
+ public void OnEvent(String eventName, Object? args)
+ {
+ _log?.Info($"�¼�: {eventName}, ����: {args}");
+ }
+}
+
+// �¼��ַ�
+public class EventDispatcher
+{
+ private readonly IEventListener[] _listeners;
+
+ public EventDispatcher(PluginManager manager)
+ {
+ _listeners = manager.Plugins?.OfType<IEventListener>().ToArray() ?? [];
+ }
+
+ public void Dispatch(String eventName, Object? args = null)
+ {
+ foreach (var listener in _listeners)
+ {
+ listener.OnEvent(eventName, args);
+ }
+ }
+}
+```
+
+### 3. ģ�黯Ӧ��
+
+```csharp
+// ģ��ӿ�
+public interface IModule
+{
+ String Name { get; }
+ void Configure(IObjectContainer container);
+ void Start();
+ void Stop();
+}
+
+// �û�ģ��
+[Plugin("MainApp")]
+public class UserModule : IPlugin, IModule, IDisposable
+{
+ public String Name => "�û�ģ��";
+
+ public Boolean Init(String? identity, IServiceProvider provider)
+ {
+ return identity == "MainApp";
+ }
+
+ public void Configure(IObjectContainer container)
+ {
+ container.AddTransient<IUserService, UserService>();
+ container.AddTransient<IUserRepository, UserRepository>();
+ }
+
+ public void Start()
+ {
+ XTrace.WriteLine($"{Name} ������");
+ }
+
+ public void Stop()
+ {
+ XTrace.WriteLine($"{Name} ��ֹͣ");
+ }
+
+ public void Dispose() => Stop();
+}
+
+// ������
+class Program
+{
+ static void Main()
+ {
+ var ioc = ObjectContainer.Current;
+
+ var manager = new PluginManager
+ {
+ Identity = "MainApp",
+ Provider = ioc.BuildServiceProvider()
+ };
+
+ manager.Load();
+ manager.Init();
+
+ // �����
+ foreach (var module in manager.Plugins.OfType<IModule>())
+ {
+ module.Configure(ioc);
+ }
+
+ // �����
+ foreach (var module in manager.Plugins.OfType<IModule>())
+ {
+ module.Start();
+ }
+
+ Console.WriteLine("��������˳�...");
+ Console.ReadKey();
+
+ manager.Dispose();
+ }
+}
+```
+
+### 4. ���Ŀ¼����
+
+```csharp
+public class PluginLoader
+{
+ public void LoadFromDirectory(String path)
+ {
+ if (!Directory.Exists(path)) return;
+
+ // ���ز��Ŀ¼�µ����� DLL
+ foreach (var file in Directory.GetFiles(path, "*.dll"))
+ {
+ try
+ {
+ Assembly.LoadFrom(file);
+ }
+ catch (Exception ex)
+ {
+ XTrace.WriteException(ex);
+ }
+ }
+ }
+}
+
+// ʹ��
+var loader = new PluginLoader();
+loader.LoadFromDirectory("plugins");
+
+var manager = new PluginManager { Identity = "MyApp" };
+manager.Load(); // �ᷢ���¼��صij����еIJ��
+manager.Init();
+```
+
+## ���ʵ��
+
+### 1. ����ӿ����
+
+```csharp
+// ������������չ��ӿ�
+public interface IPlugin
+{
+ Boolean Init(String? identity, IServiceProvider provider);
+}
+
+// ���ܽӿ������ӿڷ���
+public interface IDataExporter
+{
+ String Format { get; }
+ Byte[] Export(Object data);
+}
+
+// ���ͬʱʵ�������ӿ�
+[Plugin("ExportSystem")]
+public class ExcelExporter : IPlugin, IDataExporter
+{
+ public String Format => "xlsx";
+
+ public Boolean Init(String? identity, IServiceProvider provider) => true;
+
+ public Byte[] Export(Object data) { /* ... */ }
+}
+```
+
+### 2. ����ע��
+
+```csharp
+[Plugin("MyApp")]
+public class DatabasePlugin : IPlugin
+{
+ private IDbConnection? _connection;
+ private ILogger? _logger;
+
+ public Boolean Init(String? identity, IServiceProvider provider)
+ {
+ // ��������ȡ����
+ _connection = provider.GetService<IDbConnection>();
+ _logger = provider.GetService<ILogger>();
+
+ if (_connection == null)
+ {
+ _logger?.Error("δ�ҵ����ݿ�����");
+ return false;
+ }
+
+ return true;
+ }
+}
+```
+
+### 3. ������
+
+```csharp
+[Plugin("MyApp")]
+public class SafePlugin : IPlugin
+{
+ public Boolean Init(String? identity, IServiceProvider provider)
+ {
+ try
+ {
+ // ��ʼ����
+ return true;
+ }
+ catch (Exception ex)
+ {
+ XTrace.WriteException(ex);
+ return false; // ���� false �������׳��쳣
+ }
+ }
+}
+```
+
+### 4. ��Դ�ͷ�
+
+```csharp
+[Plugin("MyApp")]
+public class ResourcePlugin : IPlugin, IDisposable
+{
+ private FileStream? _file;
+ private Boolean _disposed;
+
+ public Boolean Init(String? identity, IServiceProvider provider)
+ {
+ _file = File.OpenWrite("plugin.log");
+ return true;
+ }
+
+ public void Dispose()
+ {
+ if (_disposed) return;
+ _disposed = true;
+
+ _file?.Dispose();
+ }
+}
+```
+
+## �������
+
+- [�������� ObjectContainer](object_container-��������ObjectContainer.md)
+- [������չ Reflect](reflect-������չReflect.md)
+- [������Ӧ������ Host](host-������Ӧ������Host.md)
diff --git a/Doc/IPacket.md "b/Doc/\346\225\260\346\215\256\345\214\205IPacket.md"
similarity index 100%
rename from Doc/IPacket.md
rename to "Doc/\346\225\260\346\215\256\345\214\205IPacket.md"
diff --git "a/Doc/\346\225\260\346\215\256\346\211\251\345\261\225IOHelper.md" "b/Doc/\346\225\260\346\215\256\346\211\251\345\261\225IOHelper.md"
new file mode 100644
index 0000000..57243bd
--- /dev/null
+++ "b/Doc/\346\225\260\346\215\256\346\211\251\345\261\225IOHelper.md"
@@ -0,0 +1,562 @@
+# ������չ IOHelper
+
+## ����
+
+`IOHelper` �� NewLife.Core �е� IO ���������࣬�ṩ��Ч���������������ֽ�����ת����ѹ����ѹ������ת���ȹ��ܡ���� .NET 6+ �� `Stream.Read` ����仯�����˼����Դ�����ȷ�������п�ܰ汾����Ϊһ�¡�
+
+**�����ռ�**��`NewLife`
+**�ĵ���ַ**��https://newlifex.com/core/io_helper
+
+## ��������
+
+- **��ȷ��ȡ**��`ReadExactly` ȷ����ȡָ���ֽ�������� .NET 6+ ���ֶ�ȡ����
+- **ѹ����ѹ**��֧�� Deflate �� GZip �����㷨
+- **�ֽ���ת��**��֧�ִ��/С���ֽ���ת��
+- **ʮ�����Ʊ���**����Ч��ʮ�������ַ���ת��
+- **�䳤����**��֧�� 7-bit �����ѹ��������д
+
+## ���ٿ�ʼ
+
+```csharp
+using NewLife;
+
+// �ֽ�����תʮ�������ַ���
+var hex = new Byte[] { 0x12, 0xAB, 0xCD }.ToHex(); // "12ABCD"
+
+// ʮ�������ַ���ת�ֽ�����
+var data = "12ABCD".ToHex(); // [0x12, 0xAB, 0xCD]
+
+// Base64 �����
+var base64 = data.ToBase64();
+var bytes = base64.ToBase64();
+
+// ѹ������
+var compressed = data.Compress();
+var decompressed = compressed.Decompress();
+
+// ��ת�ַ���
+using var stream = new MemoryStream(Encoding.UTF8.GetBytes("Hello"));
+var str = stream.ToStr(); // "Hello"
+```
+
+## API �ο�
+
+### ��������
+
+#### MaxSafeArraySize
+
+```csharp
+public static Int32 MaxSafeArraySize { get; set; } = 1024 * 1024;
+```
+
+���ȫ�����С�������ô�Сʱ����ȡ���ݲ�����ǿ��ʧ�ܡ�
+
+**��;**�����������ã���������������ʱ��ȡ�������鵼��Ӧ�ñ�����
+
+**ʾ��**��
+```csharp
+// ��Ҫ������Ͷ���������ʱ���ʵ��ſ�
+IOHelper.MaxSafeArraySize = 10 * 1024 * 1024; // 10MB
+```
+
+### ��������ȡ
+
+#### ReadExactly
+
+```csharp
+public static Int32 ReadExactly(this Stream stream, Byte[] buffer, Int32 offset, Int32 count)
+public static Byte[] ReadExactly(this Stream stream, Int64 count)
+```
+
+��ȷ��ȡָ���ֽ����������ݲ������׳� `EndOfStreamException`��
+
+**����**��.NET 6 ��ʼ��`Stream.Read` ���ܷ��ز������ݣ�partial read����������ȷ����ȡ�������ݡ�
+
+**ʾ��**��
+```csharp
+using var fs = File.OpenRead("data.bin");
+
+// ��ȡ�̶����ȵ�Э��ͷ
+var header = new Byte[16];
+fs.ReadExactly(header, 0, 16);
+
+// ��ȡ������������
+var data = fs.ReadExactly(1024);
+```
+
+#### ReadAtLeast
+
+```csharp
+public static Int32 ReadAtLeast(this Stream stream, Byte[] buffer, Int32 offset, Int32 count, Int32 minimumBytes, Boolean throwOnEndOfStream = true)
+```
+
+��ȡ����ָ���ֽ�����������ȡ���൫������ `count`��
+
+**����˵��**��
+- `minimumBytes`��������Ҫ��ȡ���ֽ���
+- `throwOnEndOfStream`�����ݲ���ʱ�Ƿ��׳��쳣
+
+**ʾ��**��
+```csharp
+var buffer = new Byte[1024];
+
+// ���ٶ�ȡ 100 �ֽڣ���� 1024 �ֽ�
+var read = stream.ReadAtLeast(buffer, 0, 1024, 100, throwOnEndOfStream: false);
+if (read < 100)
+{
+ Console.WriteLine("���ݲ���");
+}
+```
+
+#### ReadBytes
+
+```csharp
+public static Byte[] ReadBytes(this Stream stream, Int64 length)
+```
+
+�����ж�ȡָ�����ȵ��ֽ����顣
+
+**����˵��**��
+- `length`��Ҫ��ȡ���ֽ�����-1 ��ʾ��ȡ����ĩβ
+
+**ʾ��**��
+```csharp
+// ��ȡָ������
+var data = stream.ReadBytes(1024);
+
+// ��ȡȫ��ʣ������
+var all = stream.ReadBytes(-1);
+```
+
+### �������
+
+#### Write
+
+```csharp
+public static Stream Write(this Stream des, params Byte[] src)
+```
+
+���ֽ�����д����������
+
+**ʾ��**��
+```csharp
+using var ms = new MemoryStream();
+ms.Write(new Byte[] { 1, 2, 3 });
+ms.Write(new Byte[] { 4, 5, 6 });
+```
+
+#### WriteArray / ReadArray
+
+```csharp
+public static Stream WriteArray(this Stream des, params Byte[] src)
+public static Byte[] ReadArray(this Stream des)
+```
+
+д��/��ȡ������ǰ���ֽ����飨ʹ�� 7-bit ����������Ϊ���ȣ���
+
+**ʾ��**��
+```csharp
+using var ms = new MemoryStream();
+
+// д�������ǰ������
+ms.WriteArray(new Byte[] { 1, 2, 3, 4, 5 });
+
+// ��ȡ
+ms.Position = 0;
+var data = ms.ReadArray(); // [1, 2, 3, 4, 5]
+```
+
+### ѹ����ѹ
+
+#### Compress / Decompress��Deflate��
+
+```csharp
+public static Stream Compress(this Stream inStream, Stream? outStream = null)
+public static Stream Decompress(this Stream inStream, Stream? outStream = null)
+public static Byte[] Compress(this Byte[] data)
+public static Byte[] Decompress(this Byte[] data)
+```
+
+ʹ�� Deflate �㷨ѹ��/��ѹ���ݡ�
+
+**ʾ��**��
+```csharp
+// ѹ���ֽ�����
+var data = Encoding.UTF8.GetBytes("Hello World!");
+var compressed = data.Compress();
+var decompressed = compressed.Decompress();
+
+// ѹ��������
+using var input = new MemoryStream(data);
+using var output = new MemoryStream();
+input.Compress(output);
+```
+
+#### CompressGZip / DecompressGZip
+
+```csharp
+public static Stream CompressGZip(this Stream inStream, Stream? outStream = null)
+public static Stream DecompressGZip(this Stream inStream, Stream? outStream = null)
+public static Byte[] CompressGZip(this Byte[] data)
+public static Byte[] DecompressGZip(this Byte[] data)
+```
+
+ʹ�� GZip �㷨ѹ��/��ѹ���ݡ�GZip ��ʽ�����ļ�ͷ��Ϣ�������Ը��á�
+
+**ʾ��**��
+```csharp
+var data = File.ReadAllBytes("large-file.txt");
+var gzipped = data.CompressGZip();
+File.WriteAllBytes("large-file.txt.gz", gzipped);
+```
+
+### �ֽ���ת��
+
+#### ToUInt16 / ToUInt32 / ToUInt64
+
+```csharp
+public static UInt16 ToUInt16(this Byte[] data, Int32 offset = 0, Boolean isLittleEndian = true)
+public static UInt32 ToUInt32(this Byte[] data, Int32 offset = 0, Boolean isLittleEndian = true)
+public static UInt64 ToUInt64(this Byte[] data, Int32 offset = 0, Boolean isLittleEndian = true)
+```
+
+���ֽ������ȡ������֧�ִ��/С���ֽ���
+
+**ʾ��**��
+```csharp
+var data = new Byte[] { 0x01, 0x00, 0x00, 0x00 };
+
+// С����Ĭ�ϣ�
+var value1 = data.ToUInt32(); // 1
+// �����
+var value2 = data.ToUInt32(isLittleEndian: false); // 16777216
+```
+
+#### GetBytes
+
+```csharp
+public static Byte[] GetBytes(this Int16 value, Boolean isLittleEndian = true)
+public static Byte[] GetBytes(this Int32 value, Boolean isLittleEndian = true)
+public static Byte[] GetBytes(this Int64 value, Boolean isLittleEndian = true)
+// ... ��������
+```
+
+������ת��Ϊ�ֽ����顣
+
+**ʾ��**��
+```csharp
+var bytes1 = 12345.GetBytes(); // ����
+var bytes2 = 12345.GetBytes(isLittleEndian: false); // �����
+```
+
+### ʮ�����Ʊ���
+
+#### ToHex
+
+```csharp
+public static String ToHex(this Byte[] data, Int32 offset = 0, Int32 count = -1)
+public static String ToHex(this Byte[] data, String? separate, Int32 lineSize = 0)
+```
+
+���ֽ�����ת��Ϊʮ�������ַ�����
+
+**ʾ��**��
+```csharp
+var data = new Byte[] { 0x12, 0xAB, 0xCD, 0xEF };
+
+// ����ת��
+data.ToHex() // "12ABCDEF"
+
+// ���ָ���
+data.ToHex("-") // "12-AB-CD-EF"
+data.ToHex(" ") // "12 AB CD EF"
+
+// ������ʾ
+var largeData = new Byte[32];
+largeData.ToHex(" ", lineSize: 16) // ÿ 16 �ֽ�һ��
+```
+
+#### ToHex���ַ���ת�ֽ����飩
+
+```csharp
+public static Byte[] ToHex(this String? data)
+```
+
+��ʮ�������ַ���ת��Ϊ�ֽ����顣
+
+**ʾ��**��
+```csharp
+"12ABCDEF".ToHex() // [0x12, 0xAB, 0xCD, 0xEF]
+"12-AB-CD-EF".ToHex() // [0x12, 0xAB, 0xCD, 0xEF]���Զ����Էָ�����
+"12 AB CD EF".ToHex() // [0x12, 0xAB, 0xCD, 0xEF]
+```
+
+### Base64 ����
+
+#### ToBase64
+
+```csharp
+public static String ToBase64(this Byte[] data)
+public static Byte[] ToBase64(this String? data)
+```
+
+Base64 ����롣
+
+**ʾ��**��
+```csharp
+// ����
+var data = Encoding.UTF8.GetBytes("Hello");
+var base64 = data.ToBase64(); // "SGVsbG8="
+
+// ����
+var bytes = base64.ToBase64(); // [72, 101, 108, 108, 111]
+```
+
+### �ַ���ת��
+
+#### ToStr
+
+```csharp
+public static String ToStr(this Stream stream, Encoding? encoding = null)
+public static String ToStr(this Byte[] buf, Encoding? encoding = null, Int32 offset = 0, Int32 count = -1)
+```
+
+�������ֽ�����ת��Ϊ�ַ������Զ����� BOM��
+
+**ʾ��**��
+```csharp
+// ��ת�ַ���
+using var stream = new MemoryStream(Encoding.UTF8.GetBytes("Hello"));
+var str = stream.ToStr(); // "Hello"
+
+// �ֽ�����ת�ַ���
+var data = Encoding.UTF8.GetBytes("����");
+var text = data.ToStr(Encoding.UTF8); // "����"
+```
+
+### �䳤��������
+
+#### WriteEncodedInt / ReadEncodedInt
+
+```csharp
+public static Stream WriteEncodedInt(this Stream stream, Int32 value)
+public static Int32 ReadEncodedInt(this Stream stream)
+```
+
+ʹ�� 7-bit �����д�䳤������Сֵռ�ø����ֽڡ�
+
+**�������**��
+- 0-127��1 �ֽ�
+- 128-16383��2 �ֽ�
+- 16384-2097151��3 �ֽ�
+- �Դ�����
+
+**ʾ��**��
+```csharp
+using var ms = new MemoryStream();
+
+// д��Сֵֻ�� 1 �ֽ�
+ms.WriteEncodedInt(100); // 1 �ֽ�
+
+// д���ֵ��Ҫ�����ֽ�
+ms.WriteEncodedInt(10000); // 2 �ֽ�
+
+// ��ȡ
+ms.Position = 0;
+var v1 = ms.ReadEncodedInt(); // 100
+var v2 = ms.ReadEncodedInt(); // 10000
+```
+
+### ʱ���д
+
+#### WriteDateTime / ReadDateTime
+
+```csharp
+public static Stream WriteDateTime(this Stream stream, DateTime dt)
+public static DateTime ReadDateTime(this Stream stream)
+```
+
+�� Unix ʱ������룩��ʽ��дʱ�䣬4 �ֽڴ洢��
+
+**ʾ��**��
+```csharp
+using var ms = new MemoryStream();
+
+ms.WriteDateTime(DateTime.Now);
+
+ms.Position = 0;
+var dt = ms.ReadDateTime();
+```
+
+### �ֽ��������
+
+#### ReadBytes
+
+```csharp
+public static Byte[] ReadBytes(this Byte[] src, Int32 offset, Int32 count)
+```
+
+���ֽ������и���ָ����Χ�����ݡ�
+
+**ʾ��**��
+```csharp
+var data = new Byte[] { 1, 2, 3, 4, 5 };
+var part = data.ReadBytes(1, 3); // [2, 3, 4]
+var rest = data.ReadBytes(2, -1); // [3, 4, 5]��-1 ��ʾ��ĩβ��
+```
+
+#### Write
+
+```csharp
+public static Int32 Write(this Byte[] dst, Int32 dstOffset, Byte[] src, Int32 srcOffset = 0, Int32 count = -1)
+```
+
+���ֽ�����д�����ݡ�
+
+**ʾ��**��
+```csharp
+var buffer = new Byte[10];
+var data = new Byte[] { 1, 2, 3 };
+var written = buffer.Write(0, data); // д�� 3 �ֽ�
+```
+
+#### CopyTo��ָ�����ȣ�
+
+```csharp
+public static void CopyTo(this Stream source, Stream destination, Int64 length, Int32 bufferSize)
+```
+
+��Դ������ָ���������ݵ�Ŀ������
+
+**ʾ��**��
+```csharp
+using var source = File.OpenRead("large-file.bin");
+using var dest = File.Create("part.bin");
+
+// ֻ����ǰ 1MB
+source.CopyTo(dest, 1024 * 1024, bufferSize: 81920);
+```
+
+## ʹ�ó���
+
+### 1. ���������
+
+```csharp
+public class ProtocolParser
+{
+ public Message Parse(Stream stream)
+ {
+ // ��ȡ�̶����ȵ�Э��ͷ
+ var header = stream.ReadExactly(8);
+
+ var magic = header.ToUInt32(0);
+ var length = header.ToUInt32(4);
+
+ // ��ȡ��Ϣ��
+ var body = stream.ReadExactly(length);
+
+ return new Message { Header = header, Body = body };
+ }
+}
+```
+
+### 2. ���������л�
+
+```csharp
+public class BinarySerializer
+{
+ public void Serialize(Stream stream, Object obj)
+ {
+ var json = JsonSerializer.Serialize(obj);
+ var data = Encoding.UTF8.GetBytes(json);
+
+ // д�볤�Ⱥ�����
+ stream.WriteArray(data);
+ }
+
+ public T Deserialize<T>(Stream stream)
+ {
+ var data = stream.ReadArray();
+ var json = data.ToStr(Encoding.UTF8);
+ return JsonSerializer.Deserialize<T>(json);
+ }
+}
+```
+
+### 3. ����ѹ������
+
+```csharp
+public class CompressedTransport
+{
+ public Byte[] Send(Byte[] data)
+ {
+ // ѹ������
+ var compressed = data.CompressGZip();
+
+ // �����������[ѹ����־][ԭʼ����][ѹ������]
+ using var ms = new MemoryStream();
+ ms.WriteByte(1); // ѹ����־
+ ms.WriteEncodedInt(data.Length); // ԭʼ����
+ ms.Write(compressed);
+
+ return ms.ToArray();
+ }
+
+ public Byte[] Receive(Byte[] packet)
+ {
+ using var ms = new MemoryStream(packet);
+ var compressed = ms.ReadByte() == 1;
+ var originalLength = ms.ReadEncodedInt();
+ var data = ms.ReadBytes(-1);
+
+ return compressed ? data.DecompressGZip() : data;
+ }
+}
+```
+
+## ���ʵ��
+
+### 1. ʹ�� ReadExactly ��� Read
+
+```csharp
+// �Ƽ���ȷ����ȡ��������
+var data = stream.ReadExactly(100);
+
+// ���Ƽ�������ֻ��ȡ��������
+var buffer = new Byte[100];
+stream.Read(buffer, 0, 100); // .NET 6+ ���ܷ���С�� 100
+```
+
+### 2. ע���ֽ���
+
+```csharp
+// ������ϵͳ����ʱע���ֽ���
+// ����Э��ͨ��ʹ�ô����
+var networkValue = data.ToUInt32(isLittleEndian: false);
+
+// ���ش洢ͨ��ʹ��С����x86/x64 Ĭ�ϣ�
+var localValue = data.ToUInt32();
+```
+
+### 3. ʹ�ö���ؼ����ڴ����
+
+```csharp
+using NewLife.Collections;
+
+// ʹ���ڴ�����
+var ms = Pool.MemoryStream.Get();
+try
+{
+ // ʹ����...
+}
+finally
+{
+ ms.Return(true); // �黹�����
+}
+```
+
+## �������
+
+- [·����չ PathHelper](path_helper-·����չPathHelper.md)
+- [��ȫ��չ SecurityHelper](security_helper-��ȫ��չSecurityHelper.md)
+- [���ݰ� IPacket](packet-���ݰ�IPacket.md)
diff --git a/Doc/DbTable.md "b/Doc/\346\225\260\346\215\256\351\233\206DbTable.md"
similarity index 100%
rename from Doc/DbTable.md
rename to "Doc/\346\225\260\346\215\256\351\233\206DbTable.md"
diff --git "a/Doc/\346\227\245\345\277\227ILog.md" "b/Doc/\346\227\245\345\277\227ILog.md"
new file mode 100644
index 0000000..4ba0a44
--- /dev/null
+++ "b/Doc/\346\227\245\345\277\227ILog.md"
@@ -0,0 +1,610 @@
+# ��־ILog
+
+## ����
+
+`NewLife.Log.ILog` �� NewLife.Core �ĺ�����־�ӿڣ��ṩͳһ����־��¼�淶��NewLife ȫϵ�������ʹ�øýӿڼ�¼��־��
+
+ͨ����̬�� `XTrace` ���Է����ʹ����־���ܣ�֧�֣�
+- �ļ���־��Ĭ�ϣ�
+- ����̨��־
+- ������־
+- �Զ�����־ʵ��
+
+**�����ռ�**: `NewLife.Log`
+**Դ��**: [NewLife.Core/Log/ILog.cs](https://github.com/NewLifeX/X/blob/master/NewLife.Core/Log/ILog.cs)
+**�ĵ�**: https://newlifex.com/core/log
+
+---
+
+## ��������
+
+### �����÷�
+
+```csharp
+using NewLife.Log;
+
+// ��ʽ1��ʹ�� XTrace ��̬�ࣨ�Ƽ���
+XTrace.WriteLine("����һ����Ϣ");
+XTrace.WriteLine("�û�{0}��¼", "admin");
+
+// ��ʽ2��ֱ��ʹ�� ILog �ӿ�
+ILog log = XTrace.Log;
+log.Info("����һ����Ϣ");
+log.Error("����һ������");
+```
+
+### ��־����
+
+```csharp
+XTrace.Log.Debug("������Ϣ"); // ������־
+XTrace.Log.Info("��ͨ��Ϣ"); // ��Ϣ��־
+XTrace.Log.Warn("������Ϣ"); // ������־
+XTrace.Log.Error("������Ϣ"); // ������־
+XTrace.Log.Fatal("���ش���"); // ���ش�����־
+```
+
+### ����쳣
+
+```csharp
+try
+{
+ // ҵ�����
+}
+catch (Exception ex)
+{
+ XTrace.WriteException(ex); // ����쳣��ջ
+}
+```
+
+---
+
+## ILog �ӿ�
+
+```csharp
+public interface ILog
+{
+ /// <summary>д��־</summary>
+ void Write(LogLevel level, String format, params Object?[] args);
+
+ /// <summary>������־</summary>
+ void Debug(String format, params Object?[] args);
+
+ /// <summary>��Ϣ��־</summary>
+ void Info(String format, params Object?[] args);
+
+ /// <summary>������־</summary>
+ void Warn(String format, params Object?[] args);
+
+ /// <summary>������־</summary>
+ void Error(String format, params Object?[] args);
+
+ /// <summary>���ش�����־</summary>
+ void Fatal(String format, params Object?[] args);
+
+ /// <summary>�Ƿ�������־��Ϊfalseʱ������κ���־</summary>
+ Boolean Enable { get; set; }
+
+ /// <summary>��־�ȼ���ֻ������ڵ��ڸü������־��Ĭ��Info</summary>
+ LogLevel Level { get; set; }
+}
+```
+
+### ��־���� LogLevel
+
+```csharp
+public enum LogLevel
+{
+ /// <summary>�ر���־</summary>
+ Off = 0,
+
+ /// <summary>���ش�����Ӧ�ó����˳�</summary>
+ Fatal = 1,
+
+ /// <summary>����Ӱ�칦�����У���Ҫ��������</summary>
+ Error = 2,
+
+ /// <summary>���档��Ӱ�칦�ܣ�����Ҫ��ע</summary>
+ Warn = 3,
+
+ /// <summary>��Ϣ��������־��Ϣ</summary>
+ Info = 4,
+
+ /// <summary>���ԡ�������־����������Ӧ�ر�</summary>
+ Debug = 5,
+
+ /// <summary>ȫ��</summary>
+ All = 6
+}
+```
+
+---
+
+## XTrace ��̬��
+
+`XTrace` ����־����Ҫʹ����ڣ��ṩ��ݵľ�̬������
+
+### ��������
+
+```csharp
+// �����Ϣ��־
+XTrace.WriteLine("��Ϣ");
+XTrace.WriteLine("�û�{0}��{1}��¼", "admin", DateTime.Now);
+
+// ����쳣
+XTrace.WriteException(ex);
+```
+
+### �ؼ�����
+
+```csharp
+// ��ȡ��������־ʵ��
+ILog log = XTrace.Log; // Ĭ��Ϊ�ļ���־
+XTrace.Log = new ConsoleLog(); // �л�Ϊ����̨��־
+
+// �Ƿ����ģʽ
+XTrace.Debug = true; // �������ԣ����Debug������־
+
+// ��־·��
+XTrace.LogPath = "Logs"; // ������־�ļ���
+```
+
+---
+
+## Ĭ���ļ���־
+
+NewLife Ĭ��ʹ�� `TextFileLog`������־������ı��ļ���
+
+### ����
+
+- �Զ������ڷָ���־�ļ����� `2025-01-07.log`��
+- �첽д�룬������ҵ���߳�
+- �Զ����ݺ���������־
+- ֧��������־·��������ļ���С��
+
+### ����
+
+�� `NewLife.config` �� `appsettings.json` �����ã�
+
+```xml
+<!-- NewLife.config -->
+<Config>
+ <Setting>
+ <LogPath>Logs</LogPath> <!-- ��־·�� -->
+ <LogLevel>Info</LogLevel> <!-- ��־���� -->
+ <LogFileFormat>{0:yyyy-MM-dd}.log</LogFileFormat> <!-- �ļ�������ʽ -->
+ </Setting>
+</Config>
+```
+
+```json
+// appsettings.json
+{
+ "NewLife": {
+ "Setting": {
+ "LogPath": "Logs",
+ "LogLevel": "Info",
+ "LogFileFormat": "{0:yyyy-MM-dd}.log"
+ }
+ }
+}
+```
+
+### ��־�ļ�ʾ��
+
+```
+2025-01-07 10:15:23.456 Info Ӧ�ó�������
+2025-01-07 10:15:24.123 Info �û�admin��¼
+2025-01-07 10:20:15.789 Warn ���ӳ�����
+2025-01-07 10:25:30.456 Error ���ݿ����ӳ�ʱ
+System.TimeoutException: ���ӳ�ʱ
+ at MyApp.Database.Query(String sql)
+ at MyApp.Service.GetData()
+```
+
+---
+
+## ����̨��־
+
+�ڿ���̨Ӧ���У�����ʹ�� `UseConsole()` ����־���������̨��
+
+### ʹ�÷���
+
+```csharp
+class Program
+{
+ static void Main(String[] args)
+ {
+ // �ض�����־������̨
+ XTrace.UseConsole();
+
+ XTrace.WriteLine("Ӧ�ó�������");
+ XTrace.Log.Error("����һ������");
+ }
+}
+```
+
+### ��ɫ���
+
+����̨��־֧�ֲ�ɫ�������ͬ��־����ʹ�ò�ͬ��ɫ��
+- **Debug**: ��ɫ
+- **Info**: ��ɫ
+- **Warn**: ��ɫ
+- **Error**: ��ɫ
+- **Fatal**: ���ɫ
+
+### ���̲߳�ɫ
+
+```csharp
+XTrace.UseConsole(useColor: true); // ���ò�ɫ���
+
+ThreadPool.QueueUserWorkItem(_ =>
+{
+ XTrace.WriteLine("�߳�1"); // �Զ�ʹ�ò�ͬ��ɫ
+});
+
+ThreadPool.QueueUserWorkItem(_ =>
+{
+ XTrace.WriteLine("�߳�2"); // �Զ�ʹ�ò�ͬ��ɫ
+});
+```
+
+---
+
+## ������־
+
+����־ͨ�����緢�͵�Զ����־��������
+
+### ʹ�÷���
+
+```csharp
+// ����������־
+XTrace.Log = new NetworkLog("tcp://logserver:514");
+
+XTrace.WriteLine("������־�ᷢ�͵�Զ�̷�����");
+```
+
+### ����
+
+- ����ʽ��־�ռ�
+- �ֲ�ʽϵͳ��־�ۺ�
+- ������Ӧ����־���
+
+---
+
+## ������־
+
+ͬʱ��������Ŀ�ꡣ
+
+### ʹ�÷���
+
+```csharp
+using NewLife.Log;
+
+var compositeLog = new CompositeLog();
+compositeLog.Add(new TextFileLog()); // �ļ���־
+compositeLog.Add(new ConsoleLog()); // ����̨��־
+compositeLog.Add(new NetworkLog("tcp://logserver:514")); // ������־
+
+XTrace.Log = compositeLog;
+```
+
+---
+
+## �Զ�����־
+
+ʵ�� `ILog` �ӿڴ����Զ�����־��
+
+### ʾ�������ݿ���־
+
+```csharp
+public class DatabaseLog : ILog
+{
+ public Boolean Enable { get; set; } = true;
+ public LogLevel Level { get; set; } = LogLevel.Info;
+
+ public void Write(LogLevel level, String format, params Object?[] args)
+ {
+ if (!Enable || level > Level) return;
+
+ var message = args.Length > 0 ? String.Format(format, args) : format;
+
+ // д�����ݿ�
+ Database.Insert("Logs", new
+ {
+ Level = level.ToString(),
+ Message = message,
+ CreateTime = DateTime.Now
+ });
+ }
+
+ public void Debug(String format, params Object?[] args) => Write(LogLevel.Debug, format, args);
+ public void Info(String format, params Object?[] args) => Write(LogLevel.Info, format, args);
+ public void Warn(String format, params Object?[] args) => Write(LogLevel.Warn, format, args);
+ public void Error(String format, params Object?[] args) => Write(LogLevel.Error, format, args);
+ public void Fatal(String format, params Object?[] args) => Write(LogLevel.Fatal, format, args);
+}
+
+// ʹ��
+XTrace.Log = new DatabaseLog();
+```
+
+---
+
+## ʹ�ó���
+
+### 1. Ӧ�ó���������־
+
+```csharp
+class Program
+{
+ static void Main(String[] args)
+ {
+ XTrace.WriteLine("Ӧ�ó�������");
+ XTrace.WriteLine("�汾��{0}", Assembly.GetExecutingAssembly().GetName().Version);
+ XTrace.WriteLine("����ʱ��{0}", Runtime.Version);
+
+ try
+ {
+ RunApplication();
+ }
+ catch (Exception ex)
+ {
+ XTrace.WriteException(ex);
+ XTrace.Log.Fatal("Ӧ�ó����쳣�˳�");
+ }
+ }
+}
+```
+
+### 2. �ӿڵ�����־
+
+```csharp
+public class UserService
+{
+ public void Login(String username, String password)
+ {
+ XTrace.WriteLine("�û�{0}���Ե�¼", username);
+
+ if (ValidateUser(username, password))
+ {
+ XTrace.WriteLine("�û�{0}��¼�ɹ�", username);
+ }
+ else
+ {
+ XTrace.Log.Warn("�û�{0}��¼ʧ�ܣ��������", username);
+ }
+ }
+}
+```
+
+### 3. �쳣����
+
+```csharp
+try
+{
+ var data = await FetchDataAsync();
+ ProcessData(data);
+}
+catch (TimeoutException ex)
+{
+ XTrace.Log.Warn("���ݻ�ȡ��ʱ��{0}", ex.Message);
+}
+catch (Exception ex)
+{
+ XTrace.WriteException(ex);
+ throw;
+}
+```
+
+### 4. ������־
+
+```csharp
+#if DEBUG
+XTrace.Debug = true; // ����������������
+#endif
+
+XTrace.Log.Debug("��ʼ�������ݣ�{0}��", data.Length);
+foreach (var item in data)
+{
+ XTrace.Log.Debug("������Ŀ��{0}", item.Id);
+ ProcessItem(item);
+}
+XTrace.Log.Debug("���ݴ������");
+```
+
+---
+
+## ���ʵ��
+
+### 1. ����ʹ����־����
+
+```csharp
+// Debug��������Ϣ����������Ӧ�ر�
+XTrace.Log.Debug("����ֵ��{0}", value);
+
+// Info��������Ϣ����¼��Ҫ����
+XTrace.Log.Info("�û�{0}��¼", username);
+
+// Warn��������Ϣ����Ӱ�칦�ܵ����ע
+XTrace.Log.Warn("���ӳ�ʹ���ʣ�{0}%", usage);
+
+// Error��������Ϣ��Ӱ�칦������
+XTrace.Log.Error("���ݿ�����ʧ�ܣ�{0}", ex.Message);
+
+// Fatal�����ش�����Ӧ���˳�
+XTrace.Log.Fatal("�����ļ���Ӧ�ó����˳�");
+```
+
+### 2. ������־��Ϣ����
+
+```csharp
+// ���Ƽ���ѭ���������־
+foreach (var item in items) // 100��������
+{
+ XTrace.Log.Debug("������{0}", item); // ����100������־��
+}
+
+// �Ƽ����������
+var count = 0;
+foreach (var item in items)
+{
+ ProcessItem(item);
+ count++;
+}
+XTrace.Log.Info("������ɣ�{0}��", count);
+```
+
+### 3. ʹ�ýṹ����־
+
+```csharp
+// �Ƽ���ʹ��ռλ��
+XTrace.Log.Info("�û�{0}��{1}��¼��IP={2}", username, location, ip);
+
+// ���Ƽ����ַ���ƴ��
+XTrace.Log.Info("�û�" + username + "��" + location + "��¼��IP=" + ip);
+```
+
+### 4. ���ܿ���
+
+```csharp
+// �Ƽ������жϼ���
+if (XTrace.Log.Enable && XTrace.Log.Level >= LogLevel.Debug)
+{
+ var expensiveData = GetExpensiveDebugInfo(); // �������
+ XTrace.Log.Debug("������Ϣ��{0}", expensiveData);
+}
+
+// ���Ƽ���ֱ�ӵ���
+XTrace.Log.Debug("������Ϣ��{0}", GetExpensiveDebugInfo()); // ��ʹDebug�ر�Ҳ��ִ��
+```
+
+---
+
+## ���ù���
+
+### ͨ����������
+
+```csharp
+// ������־����
+XTrace.Log.Level = LogLevel.Warn; // ֻ���Warn������
+
+// �ر���־
+XTrace.Log.Enable = false;
+
+// ������־·��
+XTrace.LogPath = "C:\\Logs";
+```
+
+### ͨ�������ļ�
+
+```xml
+<!-- NewLife.config -->
+<Config>
+ <Setting>
+ <LogPath>Logs</LogPath>
+ <LogLevel>Info</LogLevel>
+ <Debug>false</Debug>
+ </Setting>
+</Config>
+```
+
+### ����ʱ��
+
+```csharp
+// ��ʱ��������
+var oldDebug = XTrace.Debug;
+XTrace.Debug = true;
+
+try
+{
+ DebugMethod();
+}
+finally
+{
+ XTrace.Debug = oldDebug; // �ָ�����
+}
+```
+
+---
+
+## ȫ���쳣����
+
+XTrace �Զ�����δ�����쳣��
+
+```csharp
+static XTrace()
+{
+ AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
+ TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
+}
+```
+
+������δ�����쳣ʱ�����Զ�����쳣��־��
+
+---
+
+## ��������
+
+### 1. ��ιر���־��
+
+```csharp
+// ��ʽ1���ر���־���
+XTrace.Log.Enable = false;
+
+// ��ʽ2��������־����ΪOff
+XTrace.Log.Level = LogLevel.Off;
+
+// ��ʽ3��ʹ�ÿ���־
+XTrace.Log = Logger.Null;
+```
+
+### 2. ��־�ļ������
+
+Ĭ����Ӧ�ó����Ŀ¼�� `Logs` �ļ����£��ļ�����ʽΪ `yyyy-MM-dd.log`��
+
+### 3. �����������Ŀ�ꣿ
+
+```csharp
+var compositeLog = new CompositeLog();
+compositeLog.Add(new TextFileLog());
+compositeLog.Add(new ConsoleLog());
+XTrace.Log = compositeLog;
+```
+
+### 4. ��־�ļ�̫����ô�죿
+
+������־���ݺ��������ԣ�
+```csharp
+var textLog = new TextFileLog();
+textLog.MaxBytes = 10 * 1024 * 1024; // ���10MB
+textLog.Backups = 10; // ����10������
+```
+
+### 5. �����ASP.NET Core��ʹ�ã�
+
+```csharp
+// Startup.cs �� Program.cs
+public void Configure(IApplicationBuilder app)
+{
+ // ��־���Զ���ʼ����ֱ��ʹ��
+ XTrace.WriteLine("Ӧ�ó�������");
+}
+```
+
+---
+
+## �����
+
+- **�����ĵ�**: https://newlifex.com/core/log
+- **Դ��**: https://github.com/NewLifeX/X/tree/master/NewLife.Core/Log
+- **��·��**: [tracer-��·��ITracer.md](tracer-��·��ITracer.md)
+
+---
+
+## ������־
+
+- **2025-01**: �����ĵ���������ϸʾ��
+- **2024**: ֧�� .NET 9.0
+- **2023**: �Ż��첽д������
+- **2022**: ����������־֧��
+- **2020**: �ع���־�ܹ���ͳһ�ӿ�
diff --git "a/Doc/\346\234\272\345\231\250\344\277\241\346\201\257MachineInfo.md" "b/Doc/\346\234\272\345\231\250\344\277\241\346\201\257MachineInfo.md"
new file mode 100644
index 0000000..e9217d2
--- /dev/null
+++ "b/Doc/\346\234\272\345\231\250\344\277\241\346\201\257MachineInfo.md"
@@ -0,0 +1,510 @@
+# ������ϢMachineInfo
+
+## ����
+
+`NewLife.MachineInfo` ���ڻ�ȡ������Ӳ����ϵͳ��Ϣ��֧��Windows��Linux��Mac�ȶ��ֲ���ϵͳ��
+
+**��Ҫ����**��
+- ��ȡ����ϵͳ��Ϣ�����ơ��汾��
+- ��ȡӲ����Ϣ��CPU���ڴ桢���̣�
+- ��ȡΨһ��ʶ��UUID��GUID�����кţ�
+- ��ȡ��̬��Ϣ��CPUռ���ʡ��ڴ�ʹ�á������ٶȣ�
+
+**�����ռ�**: `NewLife`
+**Դ��**: [NewLife.Core/Common/MachineInfo.cs](https://github.com/NewLifeX/X/blob/master/NewLife.Core/Common/MachineInfo.cs)
+**�ĵ�**: https://newlifex.com/core/machine_info
+
+---
+
+## ��������
+
+### �����÷�
+
+```csharp
+using NewLife;
+
+// ��ȡ��ǰ������Ϣ���״ε��û��ʼ����
+var machine = MachineInfo.GetCurrent();
+
+Console.WriteLine($"����ϵͳ��{machine.OSName} {machine.OSVersion}");
+Console.WriteLine($"��������{machine.Processor}");
+Console.WriteLine($"�ڴ�������{machine.Memory / 1024 / 1024 / 1024}GB");
+Console.WriteLine($"Ӳ����ʶ��{machine.UUID}");
+Console.WriteLine($"ϵͳ��ʶ��{machine.Guid}");
+```
+
+### �첽��ʼ��
+
+```csharp
+// �첽ע�������Ϣ���Ƽ���Ӧ������ʱ���ã�
+var machine = await MachineInfo.RegisterAsync();
+
+Console.WriteLine($"CPUռ�ã�{machine.CpuRate:P2}");
+Console.WriteLine($"�����ڴ棺{machine.AvailableMemory / 1024 / 1024}MB");
+```
+
+### ˢ�¶�̬����
+
+```csharp
+var machine = MachineInfo.GetCurrent();
+
+// ˢ�¶�̬���ݣ�CPU���ڴ桢����ȣ�
+machine.Refresh();
+
+Console.WriteLine($"CPUռ�ã�{machine.CpuRate:P2}");
+Console.WriteLine($"�����ڴ棺{machine.FreeMemory / 1024 / 1024}MB");
+Console.WriteLine($"�����ٶȣ�{machine.DownlinkSpeed / 1024}KB/s");
+Console.WriteLine($"�ϴ��ٶȣ�{machine.UplinkSpeed / 1024}KB/s");
+```
+
+---
+
+## ��������
+
+### ��̬��Ϣ����ʼ���䣩
+
+| ���� | ���� | ˵�� | ʾ�� |
+|-----|------|------|------|
+| `OSName` | String | ����ϵͳ���� | "Windows 11", "Ubuntu 22.04" |
+| `OSVersion` | String | ϵͳ�汾�� | "10.0.22000", "5.15.0" |
+| `Product` | String | ��Ʒ���� | "ThinkPad X1 Carbon" |
+| `Vendor` | String | ������ | "Lenovo", "Dell" |
+| `Processor` | String | �������ͺ� | "Intel Core i7-1165G7" |
+| `UUID` | String | Ӳ��Ψһ��ʶ���������кţ� | "xxxx-xxxx-xxxx" |
+| `Guid` | String | ����Ψһ��ʶ��ϵͳID�� | "xxxx-xxxx-xxxx" |
+| `Serial` | String | ��������к� | "PF2ABCDE" |
+| `Board` | String | ������Ϣ | "20XWCTO1WW" |
+| `DiskID` | String | �������к� | "1234567890" |
+| `Memory` | UInt64 | �ڴ��������ֽڣ� | 17179869184 (16GB) |
+
+### ��̬��Ϣ����Ҫˢ�£�
+
+| ���� | ���� | ˵�� |
+|-----|------|------|
+| `AvailableMemory` | UInt64 | �����ڴ棨�ֽڣ� |
+| `FreeMemory` | UInt64 | �����ڴ棨�ֽڣ� |
+| `CpuRate` | Double | CPUռ���ʣ�0-1�� |
+| `UplinkSpeed` | UInt64 | ���������ٶȣ��ֽ�/�룩 |
+| `DownlinkSpeed` | UInt64 | ���������ٶȣ��ֽ�/�룩 |
+| `Temperature` | Double | �¶ȣ��ȣ� |
+| `Battery` | Double | ���ʣ�ࣨ0-1�� |
+
+---
+
+## �����
+
+### RegisterAsync - �첽ע��
+
+```csharp
+/// <summary>�첽ע��һ����ʼ����Ļ�����Ϣʵ��</summary>
+public static Task<MachineInfo> RegisterAsync()
+```
+
+**�ص�**��
+- �첽ִ�У����������߳�
+- �״ε���ʱ��ʼ��������ֱ�ӷ��ػ�����
+- �Զ����浽�ļ���`machine_info.json`�����ӿ���������ٶ�
+- ע�ᵽ�������� `ObjectContainer`
+
+**ʾ��**��
+```csharp
+// Ӧ������ʱ�첽ע��
+await MachineInfo.RegisterAsync();
+
+// ����ֱ��ʹ��
+var machine = MachineInfo.Current;
+```
+
+### GetCurrent - ��ȡ��ǰʵ��
+
+```csharp
+/// <summary>��ȡ��ǰ��Ϣ�����δ������ȴ��첽ע����</summary>
+public static MachineInfo GetCurrent()
+```
+
+**ʾ��**��
+```csharp
+var machine = MachineInfo.GetCurrent();
+Console.WriteLine(machine.OSName);
+```
+
+### Refresh - ˢ�¶�̬����
+
+```csharp
+/// <summary>ˢ�¶�̬���ݣ�CPU���ڴ桢����ȣ�</summary>
+public void Refresh()
+```
+
+**ʾ��**��
+```csharp
+var machine = MachineInfo.GetCurrent();
+machine.Refresh(); // ����CPUռ�á��ڴ�ʹ�õ�
+
+Console.WriteLine($"CPU: {machine.CpuRate:P}");
+```
+
+---
+
+## Ψһ��ʶ˵��
+
+### UUID��Ӳ����ʶ��
+
+- **��Դ**���������к�
+- **�ص�**����Ӳ�������������仯
+- **ע��**������Ʒ�ƣ���ijЩ���ƻ��������ظ�
+
+```csharp
+var uuid = machine.UUID; // �� "A1B2C3D4-E5F6-..."
+```
+
+### Guid��ϵͳ��ʶ��
+
+- **��Դ**��
+ - Windows��ע��� `MachineGuid`
+ - Linux��`/etc/machine-id`
+ - Android��`android_id`
+- **�ص�**�������ϵͳ��װ����װϵͳ��仯
+- **ע��**��Ghostϵͳ�����ظ�
+
+```csharp
+var guid = machine.Guid; // �� "B1C2D3E4-F5A6-..."
+```
+
+### Serial�����кţ�
+
+- **��Դ**����������кţ�BIOS��
+- **�ص�**��Ʒ�ƻ����У���ʼDZ���ǩһ��
+- **ע��**����װ��ͨ��Ϊ��
+
+```csharp
+var serial = machine.Serial; // �� "PF2ABCDE"
+```
+
+### DiskID���������кţ�
+
+- **��Դ**��ϵͳ�����к�
+- **�ص�**�������Ӳ����
+- **ע��**������Ӳ�̺�仯
+
+---
+
+## �ڴ���Ϣ���
+
+### AvailableMemory�������ڴ棩
+
+**�Ƽ�����Ӧ�����ұ����ͼ�ظ澯**
+
+- **Linux**��`MemAvailable`���ں������ɰ�ȫ������ڴ棩
+- **Windows**��`ullAvailPhys`����ǰ���������ڴ棩
+
+```csharp
+if (machine.AvailableMemory < 100 * 1024 * 1024) // ��100MB
+{
+ Console.WriteLine("�ڴ治�㣬�ܾ�������");
+}
+```
+
+### FreeMemory�������ڴ棩
+
+**�ʺ����ڼ��չʾ���˹�����**
+
+- **Linux**��`MemFree + Buffers + Cached + SReclaimable - Shmem`
+- **Windows**���� `AvailableMemory` һ��
+
+```csharp
+Console.WriteLine($"�����ڴ棺{machine.FreeMemory / 1024 / 1024}MB");
+```
+
+---
+
+## ʹ�ó���
+
+### 1. Ӧ�ü��
+
+```csharp
+var timer = new TimerX(async _ =>
+{
+ var machine = MachineInfo.GetCurrent();
+ machine.Refresh();
+
+ // �ϱ��������
+ await ReportMetrics(new
+ {
+ CpuRate = machine.CpuRate,
+ AvailableMemory = machine.AvailableMemory,
+ DownlinkSpeed = machine.DownlinkSpeed,
+ UplinkSpeed = machine.UplinkSpeed
+ });
+}, null, 0, 60000); // ÿ�����ϱ�
+```
+
+### 2. �豸ע��
+
+```csharp
+var machine = await MachineInfo.RegisterAsync();
+
+var device = new Device
+{
+ UUID = machine.UUID,
+ Guid = machine.Guid,
+ OSName = machine.OSName,
+ OSVersion = machine.OSVersion,
+ Processor = machine.Processor,
+ Memory = machine.Memory
+};
+
+await RegisterDevice(device);
+```
+
+### 3. ��Ȩ��֤
+
+```csharp
+var machine = MachineInfo.GetCurrent();
+
+// ����Ӳ����ʶ��֤��Ȩ
+if (!IsLicenseValid(machine.UUID))
+{
+ throw new UnauthorizedAccessException("δ��Ȩ���豸");
+}
+```
+
+### 4. ����Ӧ��Դ����
+
+```csharp
+var machine = MachineInfo.GetCurrent();
+var cpuCount = Environment.ProcessorCount;
+var memoryGB = machine.Memory / 1024 / 1024 / 1024;
+
+// ���ݻ������õ����̳߳ش�С
+ThreadPool.SetMinThreads(cpuCount * 2, cpuCount * 2);
+
+// �����ڴ��С������������
+var cacheSize = (Int32)(memoryGB * 0.1 * 1024 * 1024 * 1024); // 10%�ڴ�
+```
+
+### 5. ���ܸ澯
+
+```csharp
+var machine = MachineInfo.GetCurrent();
+machine.Refresh();
+
+if (machine.CpuRate > 0.9)
+{
+ SendAlert("CPUʹ���ʹ��ߣ�" + machine.CpuRate.ToString("P"));
+}
+
+if (machine.AvailableMemory < 100 * 1024 * 1024)
+{
+ SendAlert("�����ڴ治�㣺" + machine.AvailableMemory / 1024 / 1024 + "MB");
+}
+```
+
+---
+
+## ���ʵ��
+
+### 1. Ӧ������ʱ�첽ע��
+
+```csharp
+class Program
+{
+ static async Task Main(String[] args)
+ {
+ // �첽ע�������Ϣ��������������
+ _ = MachineInfo.RegisterAsync();
+
+ // ����Ӧ�ó�ʼ��
+ await StartApplication();
+ }
+}
+```
+
+### 2. ʹ�õ���ģʽ
+
+```csharp
+// MachineInfo �ڲ���ʵ�ֵ���
+var machine = MachineInfo.Current; // ʹ����ע���ʵ��
+```
+
+### 3. ����ˢ�¶�̬����
+
+```csharp
+// ��ҪƵ��ˢ�£�����������1��
+var timer = new TimerX(_ =>
+{
+ MachineInfo.Current?.Refresh();
+}, null, 0, 1000);
+```
+
+### 4. ���������
+
+```csharp
+// ������Ϣ���Զ����浽��
+// - {Temp}/machine_info.json
+// - {DataPath}/machine_info.json
+
+// �´�����ʱ�Զ����ػ��棬�ӿ��ʼ���ٶ�
+```
+
+---
+
+## ��չ����
+
+### �Զ��������Ϣ�ṩ��
+
+```csharp
+public class CustomMachineInfo : IMachineInfo
+{
+ public void Init(MachineInfo info)
+ {
+ // �Զ����ʼ����
+ info["CustomField"] = "CustomValue";
+ }
+
+ public void Refresh(MachineInfo info)
+ {
+ // �Զ���ˢ����
+ info["Timestamp"] = DateTime.Now;
+ }
+}
+
+// ע���Զ����ṩ��
+MachineInfo.Provider = new CustomMachineInfo();
+await MachineInfo.RegisterAsync();
+```
+
+### ʹ����չ����
+
+```csharp
+var machine = MachineInfo.GetCurrent();
+
+// ������չ����
+machine["AppVersion"] = "1.0.0";
+machine["DeployTime"] = DateTime.Now;
+
+// ��ȡ��չ����
+var version = machine["AppVersion"] as String;
+```
+
+---
+
+## ע������
+
+### 1. �첽��ʼ��
+
+```csharp
+// �Ƽ����첽ע��
+await MachineInfo.RegisterAsync();
+
+// ���Ƽ���ͬ���ȴ�
+var machine = MachineInfo.GetCurrent(); // ��������
+```
+
+### 2. Ȩ��Ҫ��
+
+ijЩ��Ϣ��Ҫ�ض�Ȩ�ޣ�
+- **Windows**����ȡע�����Ҫ����ԱȨ�ޣ����ּ���
+- **Linux**����ȡ `/sys` �� `/proc` ͨ����Ҫ root Ȩ��
+- **����**������ͨ�û����У���ȡʧ��ʱʹ��Ĭ��ֵ
+
+### 3. Ψһ��ʶ�����ظ�
+
+- **UUID**�����ְ��ƻ�/����������ظ�
+- **Guid**��Ghostϵͳ�����ظ�
+- **����**����϶����ʶ����ΨһID
+
+```csharp
+var uniqueId = $"{machine.UUID}_{machine.Guid}_{machine.DiskID}".MD5();
+```
+
+### 4. ���ܿ���
+
+- **��ʼ��**���״�ִ�н�����100-500ms��������ʹ�û���
+- **ˢ��**��ÿ�ε��������ܿ����������Ƶ����
+- **����**����ʱˢ�£���ÿ��һ�Σ�����ʵʱˢ��
+
+---
+
+## ��ƽ̨֧��
+
+### Windows
+
+֧�֣�
+- ? OSName, OSVersion
+- ? Processor, Memory
+- ? UUID���������кţ�
+- ? Guid��MachineGuid��
+- ? Serial, Product, Vendor
+- ? CpuRate, AvailableMemory
+- ? UplinkSpeed, DownlinkSpeed
+
+### Linux
+
+֧�֣�
+- ? OSName, OSVersion
+- ? Processor, Memory
+- ? UUID��DMI��
+- ? Guid��/etc/machine-id��
+- ? CpuRate, AvailableMemory
+- ? UplinkSpeed, DownlinkSpeed
+- ?? Serial, Product�������豸��֧�֣�
+
+### macOS
+
+֧�֣�
+- ? OSName, OSVersion
+- ? Processor, Memory
+- ? UUID��Hardware UUID��
+- ?? ������Ϣ֧������
+
+---
+
+## ��������
+
+### 1. UUID Ϊʲô�ǿգ�
+
+����ԭ��
+- ���������
+- ���ƻ�û���������к�
+- Ȩ����
+
+�����ʹ�� `Guid` ����϶����ʶ��
+
+### 2. Guid Ϊ `0-xxxx` ��ʽ��
+
+��ʾ����ȡϵͳ��ʶ���Զ����ɵ����GUID��
+
+### 3. ˢ�º����ݲ��䣿
+
+��飺
+- �Ƿ���Ȩ��ȡϵͳ��Ϣ
+- ˢ�¼���Ƿ���̣������1�룩
+
+### 4. ��λ�ȡ���������ٶȣ�
+
+```csharp
+var interfaces = NetworkInterface.GetAllNetworkInterfaces();
+foreach (var ni in interfaces)
+{
+ var stats = ni.GetIPv4Statistics();
+ Console.WriteLine($"{ni.Name}: {stats.BytesReceived} / {stats.BytesSent}");
+}
+```
+
+---
+
+## �����
+
+- **�����ĵ�**: https://newlifex.com/core/machine_info
+- **Դ��**: https://github.com/NewLifeX/X/blob/master/NewLife.Core/Common/MachineInfo.cs
+- **����**: [setting-��������Setting.md](setting-��������Setting.md)
+
+---
+
+## ������־
+
+- **2025-01**: �����ĵ���������ϸ˵��
+- **2024**: ֧�� .NET 9.0���Ż���ƽ̨֧��
+- **2023**: ���� AvailableMemory �� FreeMemory
+- **2022**: ���������ٶȡ��¶ȡ���صȶ�̬��Ϣ
+- **2020**: ��ʼ�汾��֧�ֻ���Ӳ����Ϣ��ȡ
diff --git a/Doc/PooledByteBufferWriter.md "b/Doc/\346\261\240\345\214\226\345\206\231\345\205\245\345\231\250PooledByteBufferWriter.md"
similarity index 100%
rename from Doc/PooledByteBufferWriter.md
rename to "Doc/\346\261\240\345\214\226\345\206\231\345\205\245\345\231\250PooledByteBufferWriter.md"
diff --git "a/Doc/\347\261\273\345\236\213\350\275\254\346\215\242Utility.md" "b/Doc/\347\261\273\345\236\213\350\275\254\346\215\242Utility.md"
new file mode 100644
index 0000000..32b64e3
--- /dev/null
+++ "b/Doc/\347\261\273\345\236\213\350\275\254\346\215\242Utility.md"
@@ -0,0 +1,374 @@
+# ����ת�� Utility
+
+## ����
+
+`Utility` �� NewLife.Core ��������Ĺ����࣬�ṩ��Ч����ȫ������ת����չ����������ת��������֧��Ĭ��ֵ����ת��ʧ��ʱ����Ĭ��ֵ�����׳��쳣����������ճ������е�����ת��������
+
+**�����ռ�**��`NewLife`
+**�ĵ���ַ**��https://newlifex.com/core/utility
+
+## ��������
+
+- **��ȫת��**������ת��ʧ��ʱ����Ĭ��ֵ�����׳��쳣
+- **��չ����**��ֱ���ڶ����ϵ��� `.ToInt()`��`.ToDateTime()` ��
+- **������֧��**��֧���ַ�����ȫ���ַ����ֽ����顢ʱ����ȶ�������
+- **������**����Գ�����������Ż������ⲻ��Ҫ���ڴ����
+- **����չ**��ͨ�� `DefaultConvert` ��֧���Զ���ת����
+
+## ���ٿ�ʼ
+
+```csharp
+using NewLife;
+
+// �ַ���ת����
+var num = "123".ToInt(); // 123
+var num2 = "abc".ToInt(-1); // -1��ת��ʧ�ܷ���Ĭ��ֵ��
+
+// �ַ���תʱ��
+var dt = "2024-01-15".ToDateTime();
+var dt2 = "invalid".ToDateTime(); // DateTime.MinValue
+
+// ����ת����
+var flag = "true".ToBoolean(); // true
+var flag2 = "1".ToBoolean(); // true
+var flag3 = "yes".ToBoolean(); // true
+```
+
+## API �ο�
+
+### ����ת��
+
+#### ToInt
+
+```csharp
+public static Int32 ToInt(this Object? value, Int32 defaultValue = 0)
+```
+
+������ת��Ϊ32λ������
+
+**֧�ֵ���������**��
+- �ַ�������ȫ�����֣�
+- �ֽ����飨С����1-4�ֽڣ�
+- DateTime��תΪUnix�룬����ʱ��ת����
+- DateTimeOffset��תΪUnix�룩
+- ʵ�� `IConvertible` ������
+
+**ʾ��**��
+```csharp
+// ����ת��
+"123".ToInt() // 123
+" 456 ".ToInt() // 456���Զ�ȥ���ո�
+"������".ToInt() // 123��֧��ȫ�����֣�
+"1,234,567".ToInt() // 1234567��֧��ǧ��λ��
+
+// �ֽ�����ת����С����
+new Byte[] { 0x01 }.ToInt() // 1
+new Byte[] { 0x01, 0x00 }.ToInt() // 1
+new Byte[] { 0x01, 0x00, 0x00, 0x00 }.ToInt() // 1
+
+// ʱ��תUnix��
+DateTime.Now.ToInt() // ��ǰUnixʱ������룩
+
+// ת��ʧ�ܷ���Ĭ��ֵ
+"abc".ToInt() // 0
+"abc".ToInt(-1) // -1
+((Object?)null).ToInt() // 0
+```
+
+#### ToLong
+
+```csharp
+public static Int64 ToLong(this Object? value, Int64 defaultValue = 0)
+```
+
+������ת��Ϊ64λ��������
+
+**�����**��
+- DateTime תΪ Unix ���루����ʱ��ת����
+- �ֽ�����֧�� 1-8 �ֽ�
+
+**ʾ��**��
+```csharp
+"9223372036854775807".ToLong() // Int64.MaxValue
+DateTime.Now.ToLong() // ��ǰUnixʱ��������룩
+```
+
+### ������ת��
+
+#### ToDouble
+
+```csharp
+public static Double ToDouble(this Object? value, Double defaultValue = 0)
+```
+
+������ת��Ϊ˫���ȸ�������
+
+**ʾ��**��
+```csharp
+"3.14".ToDouble() // 3.14
+"3.14E+10".ToDouble() // 31400000000��֧�ֿ�ѧ��������
+"1,234.56".ToDouble() // 1234.56��֧��ǧ��λ��
+```
+
+#### ToDecimal
+
+```csharp
+public static Decimal ToDecimal(this Object? value, Decimal defaultValue = 0)
+```
+
+������ת��Ϊ�߾��ȸ������������ڽ��ڼ���Ⱦ���Ҫ��ߵij�����
+
+**ʾ��**��
+```csharp
+"123456789.123456789".ToDecimal() // ��ȷ����С��
+```
+
+### ����ֵת��
+
+#### ToBoolean
+
+```csharp
+public static Boolean ToBoolean(this Object? value, Boolean defaultValue = false)
+```
+
+������ת��Ϊ����ֵ��
+
+**֧�ֵ���ֵ**��`true`��`True`��`1`��`y`��`yes`��`on`��`enable`��`enabled`
+**֧�ֵļ�ֵ**��`false`��`False`��`0`��`n`��`no`��`off`��`disable`��`disabled`
+
+**ʾ��**��
+```csharp
+"true".ToBoolean() // true
+"True".ToBoolean() // true
+"1".ToBoolean() // true
+"yes".ToBoolean() // true
+"on".ToBoolean() // true
+"enable".ToBoolean() // true
+
+"false".ToBoolean() // false
+"0".ToBoolean() // false
+"no".ToBoolean() // false
+"off".ToBoolean() // false
+
+"invalid".ToBoolean() // false��Ĭ��ֵ��
+"invalid".ToBoolean(true) // true��ָ��Ĭ��ֵ��
+```
+
+### ʱ��ת��
+
+#### ToDateTime
+
+```csharp
+public static DateTime ToDateTime(this Object? value)
+public static DateTime ToDateTime(this Object? value, DateTime defaultValue)
+```
+
+������ת��Ϊʱ�����ڡ�
+
+**֧�ֵĸ�ʽ**��
+- ������ʱ���ַ���
+- `yyyy-M-d` ��ʽ
+- `yyyy/M/d` ��ʽ
+- `yyyyMMddHHmmss` ��ʽ
+- `yyyyMMdd` ��ʽ
+- Unix �루Int32��
+- Unix ���루Int64���Զ��жϣ�
+- UTC ��ǣ�ĩβ `Z` �� ` UTC`��
+
+**ʾ��**��
+```csharp
+// �ַ���ת��
+"2024-01-15".ToDateTime()
+"2024-1-5".ToDateTime() // ֧�ֵ�λ������
+"2024/01/15".ToDateTime()
+"20240115".ToDateTime()
+"20240115120000".ToDateTime()
+"2024-01-15 12:30:45".ToDateTime()
+"2024-01-15T12:30:45Z".ToDateTime() // UTC ʱ��
+
+// Unix ʱ���ת��
+1705276800.ToDateTime() // Unix ��
+1705276800000L.ToDateTime() // Unix ���루�Զ��жϣ�
+```
+
+> **ע��**������תʱ��ʱ������ UTC �뱾��ʱ��ת�����������������У��豸����λ�ڲ�ͬʱ��������ͳһʹ�� UTC ʱ�䴫�����ת����
+
+#### ToDateTimeOffset
+
+```csharp
+public static DateTimeOffset ToDateTimeOffset(this Object? value)
+public static DateTimeOffset ToDateTimeOffset(this Object? value, DateTimeOffset defaultValue)
+```
+
+������ת��Ϊ��ʱ����ʱ�����ڡ�
+
+### ʱ���ʽ��
+
+#### ToFullString
+
+```csharp
+public static String ToFullString(this DateTime value, String? emptyValue = null)
+public static String ToFullString(this DateTime value, Boolean useMillisecond, String? emptyValue = null)
+```
+
+��ʱ���ʽ��Ϊ `yyyy-MM-dd HH:mm:ss` ����ʽ��
+
+**����˵��**��
+- `useMillisecond`���Ƿ�������룬��ʽΪ `yyyy-MM-dd HH:mm:ss.fff`
+- `emptyValue`����ʱ��Ϊ `MinValue` ʱ��ʾ������ַ���
+
+**ʾ��**��
+```csharp
+DateTime.Now.ToFullString() // "2024-01-15 12:30:45"
+DateTime.Now.ToFullString(true) // "2024-01-15 12:30:45.123"
+DateTime.MinValue.ToFullString("") // ""
+DateTime.MinValue.ToFullString("N/A") // "N/A"
+```
+
+#### Trim
+
+```csharp
+public static DateTime Trim(this DateTime value, String format = "s")
+```
+
+�ض�ʱ�侫�ȡ�
+
+**��ʽ����**��
+- `ns`�����뾫�ȣ�ʵ��Ϊ 100ns���� 1 tick��
+- `us`���뾫��
+- `ms`�����뾫��
+- `s`���뾫�ȣ�Ĭ�ϣ�
+- `m`�����Ӿ���
+- `h`��Сʱ����
+
+**ʾ��**��
+```csharp
+var dt = new DateTime(2024, 1, 15, 12, 30, 45, 123);
+dt.Trim("s") // 2024-01-15 12:30:45.000
+dt.Trim("m") // 2024-01-15 12:30:00.000
+dt.Trim("h") // 2024-01-15 12:00:00.000
+dt.Trim("ms") // ��������
+```
+
+### �ֽڵ�λ��ʽ��
+
+#### ToGMK
+
+```csharp
+public static String ToGMK(this Int64 value, String? format = null)
+public static String ToGMK(this UInt64 value, String? format = null)
+```
+
+���ֽ�����ʽ��Ϊ�ɶ��ĵ�λ�ַ�����
+
+**ʾ��**��
+```csharp
+1024L.ToGMK() // "1.00K"
+1048576L.ToGMK() // "1.00M"
+1073741824L.ToGMK() // "1.00G"
+1099511627776L.ToGMK() // "1.00T"
+
+// �Զ����ʽ
+1536L.ToGMK("n1") // "1.5K"
+1536L.ToGMK("n0") // "2K"
+```
+
+### �쳣����
+
+#### GetTrue
+
+```csharp
+public static Exception GetTrue(this Exception ex)
+```
+
+��ȡ�쳣����ʵ�ڲ��쳣���Զ���� `AggregateException`��`TargetInvocationException`��`TypeInitializationException` �Ȱ�װ�쳣��
+
+**ʾ��**��
+```csharp
+try
+{
+ // �����׳���װ�쳣�Ĵ���
+}
+catch (Exception ex)
+{
+ var realEx = ex.GetTrue();
+ Console.WriteLine(realEx.Message);
+}
+```
+
+#### GetMessage
+
+```csharp
+public static String GetMessage(this Exception ex)
+```
+
+��ȡ��ʽ�����쳣��Ϣ�����˵�����Ҫ�Ķ�ջ��Ϣ���� `System.Runtime.ExceptionServices` �ȣ���
+
+## �Զ���ת��
+
+ͨ���滻 `Utility.Convert` �����Զ�����������ת������Ϊ��
+
+```csharp
+public class MyConvert : DefaultConvert
+{
+ public override Int32 ToInt(Object? value, Int32 defaultValue)
+ {
+ // �Զ���ת����
+ if (value is MyCustomType mct)
+ return mct.Value;
+
+ return base.ToInt(value, defaultValue);
+ }
+}
+
+// ȫ���滻
+Utility.Convert = new MyConvert();
+```
+
+## ���ʵ��
+
+### 1. ʼ���ṩ�������Ĭ��ֵ
+
+```csharp
+// �Ƽ�����ȷָ��Ĭ��ֵ
+var port = config["Port"].ToInt(8080);
+var timeout = config["Timeout"].ToInt(30);
+
+// ���Ƽ���ʹ����ʽĬ��ֵ 0 ���ܵ�������
+var port = config["Port"].ToInt(); // �������ȱʧ���˿�Ϊ 0
+```
+
+### 2. ʱ���ת��ע��ʱ��
+
+```csharp
+// �������������豸�ϱ� UTC ʱ���
+var deviceTime = timestamp.ToDateTime(); // ����ʱ��ת��
+var localTime = deviceTime.ToLocalTime(); // תΪ����ʱ��
+
+// ����ʹ�� DateTimeOffset
+var dto = timestamp.ToDateTimeOffset();
+```
+
+### 3. ������ʽ���ü���
+
+```csharp
+// ��ͳд��
+Int32 value;
+if (!Int32.TryParse(str, out value))
+ value = defaultValue;
+
+// NewLife �
+var value = str.ToInt(defaultValue);
+```
+
+## ����˵��
+
+- ����ת��������Գ������ͣ�String��Int32 �ȣ������˿���·���Ż�
+- �ַ���ת��ʹ�� `Span<T>` ���ⲻ��Ҫ���ڴ����
+- ʱ���ʽ������ʹ�� `ToString()` ��ʽ���������ֶ�ƴ����������
+- �ֽ�����ת��ֱ��ʹ�� `BitConverter`�������
+
+## �������
+
+- [�ַ�����չ StringHelper](string_helper-�ַ�����չStringHelper.md)
+- [������չ IOHelper](io_helper-������չIOHelper.md)
diff --git a/Doc/Buffers.md "b/Doc/\347\274\223\345\206\262\345\214\272Buffers.md"
similarity index 100%
rename from Doc/Buffers.md
rename to "Doc/\347\274\223\345\206\262\345\214\272Buffers.md"
diff --git "a/Doc/\347\274\223\345\255\230\347\263\273\347\273\237ICache.md" "b/Doc/\347\274\223\345\255\230\347\263\273\347\273\237ICache.md"
new file mode 100644
index 0000000..3308d28
--- /dev/null
+++ "b/Doc/\347\274\223\345\255\230\347\263\273\347\273\237ICache.md"
@@ -0,0 +1,427 @@
+# ����ϵͳ ICache
+
+## ����
+
+NewLife.Core �ṩ��ͳһ�Ļ���ӿ� `ICache`��֧���ڴ滺�桢Redis ����ȶ���ʵ�֡�ͨ��ͳһ�ӿڣ������ڲ�ͬ���������л�����ʵ�֣�ͬʱ֧�ֹ���ʱ�䡢ԭ�Ӳ��������������ȸ����ԡ�
+
+**�����ռ�**��`NewLife.Caching`
+**�ĵ���ַ**��https://newlifex.com/core/icache
+
+## ��������
+
+- **ͳһ�ӿ�**��`ICache` �ӿڶ�����������
+- **������**��`MemoryCache` ���� `ConcurrentDictionary`����ֵ���ܴ� 10 �� ops
+- **�Զ�����**��֧����Թ���ʱ�䣨TTL��
+- **ԭ�Ӳ���**���������ݼ����滻��ԭ�Ӳ���
+- **��������**��������д�������翪��
+- **LRU ��̭**���ڴ滺�泬����ʱ�Զ�����
+
+## ���ٿ�ʼ
+
+### ����ʹ��
+
+```csharp
+using NewLife.Caching;
+
+// ʹ��Ĭ���ڴ滺��
+var cache = MemoryCache.Instance;
+
+// ���û��棨60����ڣ�
+cache.Set("name", "����", 60);
+
+// ��ȡ����
+var name = cache.Get<String>("name");
+
+// ɾ������
+cache.Remove("name");
+```
+
+### ����
+
+```csharp
+var cache = MemoryCache.Instance;
+
+// ����Ƿ����
+if (cache.ContainsKey("user:1"))
+{
+ var user = cache.Get<User>("user:1");
+}
+
+// ��ȡ�����ӣ����洩������
+var data = cache.GetOrAdd("data:key", k =>
+{
+ // ���治����ʱ��ִ�д˻ص���ȡ����
+ return LoadFromDatabase(k);
+}, 300);
+
+// ԭ�ӵ���
+var count = cache.Increment("visit:count", 1);
+```
+
+## API �ο�
+
+### ICache �ӿ�
+
+#### ��������
+
+```csharp
+/// <summary>��������</summary>
+String Name { get; }
+
+/// <summary>Ĭ�Ϲ���ʱ�䣨�룩</summary>
+Int32 Expire { get; set; }
+
+/// <summary>����������</summary>
+Int32 Count { get; }
+
+/// <summary>������</summary>
+ICollection<String> Keys { get; }
+```
+
+#### ��������
+
+```csharp
+/// <summary>����Ƿ����</summary>
+Boolean ContainsKey(String key);
+
+/// <summary>���û���</summary>
+/// <param name="expire">����������-1ʹ��Ĭ�ϣ�0��������</param>
+Boolean Set<T>(String key, T value, Int32 expire = -1);
+
+/// <summary>���û��棨TimeSpan��</summary>
+Boolean Set<T>(String key, T value, TimeSpan expire);
+
+/// <summary>��ȡ����</summary>
+T Get<T>(String key);
+
+/// <summary>���Ի�ȡ��������洩��</summary>
+Boolean TryGetValue<T>(String key, out T value);
+
+/// <summary>ɾ������</summary>
+Int32 Remove(String key);
+
+/// <summary>����ɾ��</summary>
+Int32 Remove(params String[] keys);
+
+/// <summary>��������</summary>
+void Clear();
+```
+
+#### ����ʱ�����
+
+```csharp
+/// <summary>���ù���ʱ��</summary>
+Boolean SetExpire(String key, TimeSpan expire);
+
+/// <summary>��ȡʣ�����ʱ��</summary>
+TimeSpan GetExpire(String key);
+```
+
+#### ��������
+
+```csharp
+/// <summary>������ȡ</summary>
+IDictionary<String, T?> GetAll<T>(IEnumerable<String> keys);
+
+/// <summary>��������</summary>
+void SetAll<T>(IDictionary<String, T> values, Int32 expire = -1);
+```
+
+#### ������
+
+```csharp
+/// <summary>���ӣ��Ѵ���ʱ�����£�</summary>
+Boolean Add<T>(String key, T value, Int32 expire = -1);
+
+/// <summary>�滻�����ؾ�ֵ</summary>
+T Replace<T>(String key, T value);
+
+/// <summary>��ȡ������</summary>
+T GetOrAdd<T>(String key, Func<String, T> callback, Int32 expire = -1);
+
+/// <summary>ԭ�ӵ���</summary>
+Int64 Increment(String key, Int64 value);
+Double Increment(String key, Double value);
+
+/// <summary>ԭ�ӵݼ�</summary>
+Int64 Decrement(String key, Int64 value);
+Double Decrement(String key, Double value);
+```
+
+### MemoryCache ��
+
+```csharp
+public class MemoryCache : Cache
+{
+ /// <summary>Ĭ��ʵ��</summary>
+ public static MemoryCache Instance { get; set; }
+
+ /// <summary>����������ʱLRU��̭��Ĭ��100000</summary>
+ public Int32 Capacity { get; set; }
+
+ /// <summary>��ʱ����������룩��Ĭ��60</summary>
+ public Int32 Period { get; set; }
+
+ /// <summary>����������¼�</summary>
+ public event EventHandler<KeyEventArgs>? KeyExpired;
+}
+```
+
+## ʹ�ó���
+
+### 1. ���ݻ���
+
+```csharp
+public class UserService
+{
+ private readonly ICache _cache;
+
+ public UserService(ICache cache)
+ {
+ _cache = cache;
+ }
+
+ public User? GetUser(Int32 id)
+ {
+ var key = $"user:{id}";
+
+ // �Ȳ黺��
+ if (_cache.TryGetValue<User>(key, out var user))
+ return user;
+
+ // ����δ���У������ݿ�
+ user = LoadUserFromDb(id);
+
+ if (user != null)
+ _cache.Set(key, user, 300); // ����5����
+
+ return user;
+ }
+}
+```
+
+### 2. ��ֹ���洩
+
+```csharp
+// ʹ�� GetOrAdd ��ֹ���洩
+var user = cache.GetOrAdd($"user:{id}", key =>
+{
+ // ��ʹ���ݿⷵ�� null��Ҳ�ᱻ����
+ return LoadUserFromDb(id);
+}, 60);
+
+// ʹ�� TryGetValue ���ֿ�ֵ�Ͳ�����
+if (cache.TryGetValue<User?>($"user:{id}", out var user))
+{
+ // �����ڣ�����Ϊ null��
+ return user;
+}
+else
+{
+ // �������ڣ���Ҫ��ѯ���ݿ�
+}
+```
+
+### 3. ������
+
+```csharp
+// ���ʼ���
+var count = cache.Increment("page:home:views", 1);
+
+// ��������
+var requests = cache.Increment($"rate:{userId}", 1);
+if (requests == 1)
+{
+ // �״η��ʣ����ù���ʱ��
+ cache.SetExpire($"rate:{userId}", TimeSpan.FromMinutes(1));
+}
+if (requests > 100)
+{
+ throw new Exception("�������Ƶ��");
+}
+```
+
+### 4. �ֲ�ʽ������ʵ��
+
+```csharp
+public class SimpleLock
+{
+ private readonly ICache _cache;
+
+ public Boolean TryLock(String key, Int32 seconds = 30)
+ {
+ // Add ֻ�ڲ�����ʱ�ɹ�
+ return _cache.Add($"lock:{key}", DateTime.Now, seconds);
+ }
+
+ public void Unlock(String key)
+ {
+ _cache.Remove($"lock:{key}");
+ }
+}
+
+// ʹ��
+var locker = new SimpleLock(cache);
+if (locker.TryLock("order:create"))
+{
+ try
+ {
+ // ִ��ҵ��
+ }
+ finally
+ {
+ locker.Unlock("order:create");
+ }
+}
+```
+
+### 5. �Ự����
+
+```csharp
+public class SessionCache
+{
+ private readonly ICache _cache;
+ private readonly Int32 _expire = 1800; // 30����
+
+ public void Set(String sessionId, Object data)
+ {
+ _cache.Set($"session:{sessionId}", data, _expire);
+ }
+
+ public T? Get<T>(String sessionId)
+ {
+ var key = $"session:{sessionId}";
+ var data = _cache.Get<T>(key);
+
+ if (data != null)
+ {
+ // ����
+ _cache.SetExpire(key, TimeSpan.FromSeconds(_expire));
+ }
+
+ return data;
+ }
+}
+```
+
+### 6. ����������
+
+```csharp
+// ������ȡ
+var keys = new[] { "user:1", "user:2", "user:3" };
+var users = cache.GetAll<User>(keys);
+
+foreach (var kv in users)
+{
+ Console.WriteLine($"{kv.Key}: {kv.Value?.Name}");
+}
+
+// ��������
+var items = new Dictionary<String, User>
+{
+ ["user:1"] = new User { Id = 1, Name = "����" },
+ ["user:2"] = new User { Id = 2, Name = "����" }
+};
+cache.SetAll(items, 300);
+```
+
+## ����ʱ��˵��
+
+| expire ֵ | ���� |
+|-----------|------|
+| < 0 | ʹ��Ĭ�Ϲ���ʱ�� `Expire` |
+| = 0 | �������� |
+| > 0 | �������� N ������ |
+
+```csharp
+// ʹ��Ĭ�Ϲ���ʱ��
+cache.Set("key1", value);
+
+// ��������
+cache.Set("key2", value, 0);
+
+// 1Сʱ�����
+cache.Set("key3", value, 3600);
+
+// ʹ�� TimeSpan
+cache.Set("key4", value, TimeSpan.FromHours(1));
+```
+
+## ����ע��
+
+```csharp
+// ע�Ỻ�����
+services.AddSingleton<ICache>(MemoryCache.Instance);
+
+// ����ʵ��
+services.AddSingleton<ICache>(sp => new MemoryCache
+{
+ Capacity = 50000,
+ Expire = 600
+});
+```
+
+## ������淶
+
+����ʹ��ð�ŷָ��IJ㼶������
+
+```
+����:��ʶ[:������]
+user:123
+user:123:profile
+order:2024:001
+config:app:debug
+```
+
+## ���ʵ��
+
+### 1. ������������
+
+```csharp
+var cache = new MemoryCache
+{
+ Capacity = 100000, // �����ڴ����
+ Period = 60 // �������
+};
+```
+
+### 2. ���������¼�
+
+```csharp
+var cache = new MemoryCache();
+cache.KeyExpired += (s, e) =>
+{
+ XTrace.WriteLine($"�������: {e.Key}");
+ // ���������ﴥ������Ԥ��
+};
+```
+
+### 3. ����� Key
+
+```csharp
+// ���Ƽ����洢�����
+cache.Set("bigdata", hugeList);
+
+// �Ƽ�����ִ洢
+foreach (var item in hugeList)
+{
+ cache.Set($"item:{item.Id}", item);
+}
+```
+
+### 4. ʹ��ǰ����
+
+```csharp
+// ��ͬģ��ʹ�ò�ͬǰ
+cache.Set("user:session:abc", data);
+cache.Set("order:temp:123", data);
+
+// ��ǰ����ɾ��
+cache.Remove("user:session:*");
+```
+
+## �������
+
+- [����� Pool](pool-�����Pool.md)
+- [�ֵ仺�� DictionaryCache](dictionary_cache-�ֵ仺��.md)
+- [ѩ���㷨 Snowflake](snowflake-ѩ���㷨Snowflake.md)
diff --git a/Doc/NetClient.md "b/Doc/\347\275\221\347\273\234\345\256\242\346\210\267\347\253\257NetClient.md"
similarity index 100%
rename from Doc/NetClient.md
rename to "Doc/\347\275\221\347\273\234\345\256\242\346\210\267\347\253\257NetClient.md"
diff --git a/Doc/NetServer.md "b/Doc/\347\275\221\347\273\234\346\234\215\345\212\241\347\253\257NetServer.md"
similarity index 100%
rename from Doc/NetServer.md
rename to "Doc/\347\275\221\347\273\234\346\234\215\345\212\241\347\253\257NetServer.md"
diff --git "a/Doc/\350\267\257\345\276\204\346\211\251\345\261\225PathHelper.md" "b/Doc/\350\267\257\345\276\204\346\211\251\345\261\225PathHelper.md"
new file mode 100644
index 0000000..e4aeac4
--- /dev/null
+++ "b/Doc/\350\267\257\345\276\204\346\211\251\345\261\225PathHelper.md"
@@ -0,0 +1,545 @@
+# ·����չ PathHelper
+
+## ����
+
+`PathHelper` �� NewLife.Core �е�·�����������࣬�ṩ��ƽ̨���ļ�·��������Ŀ¼�������ļ�ѹ����ѹ����ϣУ��ȹ��ܡ����ܴ������·���;���·�����Զ����� Windows �� Linux ��·���ָ�����
+
+**�����ռ�**��`System.IO`������ֱ��ʹ�ã�����������ã�
+**�ĵ���ַ**��https://newlifex.com/core/path_helper
+
+## ��������
+
+- **��ƽ̨·������**���Զ����� Windows��`\`���� Linux��`/`��·���ָ���
+- **����·������**��֧�����·��������·��������·��
+- **��������֧��**��ͨ�������в������������û���Ŀ¼
+- **ѹ����ѹ֧��**��֧�� zip��tar��tar.gz��7z �ȸ�ʽ
+- **�ļ���ϣУ��**��֧�� MD5��SHA1��SHA256��SHA512��CRC32
+
+## ���ٿ�ʼ
+
+```csharp
+using System.IO;
+
+// ��ȡ����·��
+var path = "config/app.json".GetFullPath();
+
+// ȷ��Ŀ¼����
+"logs/2024/01/".EnsureDirectory(false);
+
+// �ϲ�·��
+var file = "data".CombinePath("users", "config.json");
+
+// ѹ��Ŀ¼
+"output".AsDirectory().Compress("backup.zip");
+
+// ��֤�ļ���ϣ
+var valid = "app.exe".AsFile().VerifyHash("md5$1234567890abcdef");
+```
+
+## API �ο�
+
+### ·������
+
+#### BasePath
+
+```csharp
+public static String? BasePath { get; set; }
+```
+
+����Ŀ¼������ `GetBasePath` ��������Ҫ���� X ����ڲ���Ŀ¼��ר��Ϊ������������ơ�
+
+**���÷�ʽ**�������ȼ�����
+1. ���������`-BasePath /app/data` �� `--BasePath /app/data`
+2. ����������`BasePath=/app/data`
+3. Ĭ��ֵ��Ӧ�ó��������Ŀ¼
+
+#### BaseDirectory
+
+```csharp
+public static String? BaseDirectory { get; set; }
+```
+
+��Ŀ¼������ `GetFullPath` ������֧��ͨ�������в����ͻ����������á�
+
+### ·��ת��
+
+#### GetFullPath
+
+```csharp
+public static String GetFullPath(this String path)
+```
+
+��ȡ�ļ���Ŀ¼����Ӧ�ó������Ŀ¼��ȫ·����
+
+**�ص�**��
+- �Զ��������·��
+- �Զ�ת��·���ָ���
+- ֧������·����`\\server\share`��
+- ֧�� `~` ��ͷ��·��
+
+**ʾ��**��
+```csharp
+// ���·��ת����·��
+"config/app.json".GetFullPath()
+// Windows: C:\MyApp\config\app.json
+// Linux: /home/user/myapp/config/app.json
+
+// ���Ǿ���·����ԭ������
+"C:\\temp\\file.txt".GetFullPath() // C:\temp\file.txt
+"/var/log/app.log".GetFullPath() // /var/log/app.log
+
+// ����·��
+"\\\\server\\share\\file.txt".GetFullPath() // \\server\share\file.txt
+
+// ~ ��ͷ��·��
+"~/config/app.json".GetFullPath() // ȥ�� ~ ��ƴ�ӻ���Ŀ¼
+```
+
+#### GetBasePath
+
+```csharp
+public static String GetBasePath(this String path)
+```
+
+��ȡ�ļ���Ŀ¼��ȫ·�������� X ����ڲ���Ŀ¼��
+
+**ʾ��**��
+```csharp
+"logs/app.log".GetBasePath()
+// ���� BasePath ������·��
+```
+
+#### GetCurrentPath
+
+```csharp
+public static String GetCurrentPath(this String path)
+```
+
+��ȡ�ļ���Ŀ¼���ڵ�ǰ����Ŀ¼��ȫ·����
+
+**ʾ��**��
+```csharp
+"output/result.txt".GetCurrentPath()
+// ���� Environment.CurrentDirectory ������·��
+```
+
+### Ŀ¼����
+
+#### EnsureDirectory
+
+```csharp
+public static String EnsureDirectory(this String path, Boolean isfile = true)
+```
+
+ȷ��Ŀ¼���ڣ�������������
+
+**����˵��**��
+- `isfile`��·���Ƿ�Ϊ�ļ�·����`true` ʱȡĿ¼���֣�б�ܽ�β��·��ʼ����ΪĿ¼��
+
+**ʾ��**��
+```csharp
+// ȷ���ļ�����Ŀ¼����
+"logs/2024/01/app.log".EnsureDirectory(true);
+// ���� logs/2024/01/ Ŀ¼
+
+// ȷ��Ŀ¼��������
+"data/cache/".EnsureDirectory(false);
+// ���� data/cache/ Ŀ¼
+
+// б�ܽ�β��·��ʼ����ΪĿ¼
+"output/temp/".EnsureDirectory(); // isfile ����������
+```
+
+#### CombinePath
+
+```csharp
+public static String CombinePath(this String? path, params String[] ps)
+```
+
+�ϲ����·����
+
+**ʾ��**��
+```csharp
+"data".CombinePath("users", "config.json")
+// Windows: data\users\config.json
+// Linux: data/users/config.json
+
+// ֧�ֿ�·��
+"".CombinePath("logs", "app.log") // logs/app.log
+```
+
+### �����
+
+#### AsFile
+
+```csharp
+public static FileInfo AsFile(this String file)
+```
+
+��·���ַ���ת��Ϊ `FileInfo` ����
+
+**ʾ��**��
+```csharp
+var fi = "config/app.json".AsFile();
+if (fi.Exists)
+{
+ Console.WriteLine($"�ļ���С: {fi.Length}");
+}
+```
+
+#### ReadBytes
+
+```csharp
+public static Byte[] ReadBytes(this FileInfo file, Int32 offset = 0, Int32 count = -1)
+```
+
+���ļ���ȡ�ֽ����ݡ�
+
+**ʾ��**��
+```csharp
+// ��ȡ�����ļ�
+var data = "data.bin".AsFile().ReadBytes();
+
+// ��ȡָ����Χ
+var header = "data.bin".AsFile().ReadBytes(0, 100); // ǰ100�ֽ�
+var tail = "data.bin".AsFile().ReadBytes(1000, 50); // ��1000��ʼ��50�ֽ�
+```
+
+#### WriteBytes
+
+```csharp
+public static FileInfo WriteBytes(this FileInfo file, Byte[] data, Int32 offset = 0)
+```
+
+���ļ�д���ֽ����ݡ�
+
+**ʾ��**��
+```csharp
+var data = new Byte[] { 1, 2, 3, 4, 5 };
+"output.bin".AsFile().WriteBytes(data);
+```
+
+#### CopyToIfNewer
+
+```csharp
+public static Boolean CopyToIfNewer(this FileInfo fi, String destFileName)
+```
+
+����Դ�ļ���Ŀ���ļ���ʱ�Ÿ��ơ�
+
+**ʾ��**��
+```csharp
+var source = "src/app.dll".AsFile();
+if (source.CopyToIfNewer("dest/app.dll"))
+{
+ Console.WriteLine("�ļ��Ѹ���");
+}
+```
+
+### Ŀ¼����
+
+#### AsDirectory
+
+```csharp
+public static DirectoryInfo AsDirectory(this String dir)
+```
+
+��·���ַ���ת��Ϊ `DirectoryInfo` ����
+
+**ʾ��**��
+```csharp
+var di = "data/cache".AsDirectory();
+if (di.Exists)
+{
+ Console.WriteLine($"���� {di.GetFiles().Length} ���ļ�");
+}
+```
+
+#### GetAllFiles
+
+```csharp
+public static IEnumerable<FileInfo> GetAllFiles(this DirectoryInfo di, String? exts = null, Boolean allSub = false)
+```
+
+��ȡĿ¼�����з����������ļ���֧�ֶ���չ��ƥ�䡣
+
+**ʾ��**��
+```csharp
+var dir = "src".AsDirectory();
+
+// ��ȡ�����ļ�
+var allFiles = dir.GetAllFiles();
+
+// ��ȡָ����չ���ļ�
+var csharpFiles = dir.GetAllFiles("*.cs");
+
+// ����չ��ƥ�䣨�ֺš����ߡ����ŷָ���
+var codeFiles = dir.GetAllFiles("*.cs;*.xaml;*.json");
+
+// ������Ŀ¼
+var allCsharp = dir.GetAllFiles("*.cs", true);
+```
+
+#### CopyTo
+
+```csharp
+public static String[] CopyTo(this DirectoryInfo di, String destDirName, String? exts = null, Boolean allSub = false, Action<String>? callback = null)
+```
+
+����Ŀ¼�е��ļ���Ŀ��Ŀ¼��
+
+**ʾ��**��
+```csharp
+var copied = "src".AsDirectory().CopyTo("backup", "*.cs;*.json", true, name =>
+{
+ Console.WriteLine($"����: {name}");
+});
+Console.WriteLine($"������ {copied.Length} ���ļ�");
+```
+
+#### CopyToIfNewer
+
+```csharp
+public static String[] CopyToIfNewer(this DirectoryInfo di, String destDirName, String? exts = null, Boolean allSub = false, Action<String>? callback = null)
+```
+
+������ԴĿ¼�б�Ŀ��Ŀ¼���µ��ļ���
+
+**ʾ��**��
+```csharp
+var updated = "src".AsDirectory().CopyToIfNewer("dest", "*.dll;*.exe", true);
+```
+
+### ѹ����ѹ
+
+#### Extract���ļ���ѹ��
+
+```csharp
+public static void Extract(this FileInfo fi, String destDir, Boolean overwrite = false)
+```
+
+��ѹ�ļ���ָ��Ŀ¼��
+
+**֧�ָ�ʽ**��zip��tar��tar.gz��tgz��7z���� Windows��
+
+**ʾ��**��
+```csharp
+// ��ѹ zip �ļ�
+"package.zip".AsFile().Extract("output");
+
+// ��ѹ tar.gz �ļ�
+"archive.tar.gz".AsFile().Extract("output", overwrite: true);
+
+// Ĭ�Ͻ�ѹ��ͬ��Ŀ¼
+"app.zip".AsFile().Extract(""); // ��ѹ�� app/ Ŀ¼
+```
+
+#### Compress���ļ�ѹ����
+
+```csharp
+public static void Compress(this FileInfo fi, String destFile)
+```
+
+ѹ�������ļ���
+
+**ʾ��**��
+```csharp
+"large-file.log".AsFile().Compress("large-file.zip");
+"data.bin".AsFile().Compress("data.tar.gz");
+```
+
+#### Compress��Ŀ¼ѹ����
+
+```csharp
+public static void Compress(this DirectoryInfo di, String? destFile = null)
+public static void Compress(this DirectoryInfo di, String? destFile, Boolean includeBaseDirectory)
+```
+
+ѹ������Ŀ¼��
+
+**ʾ��**��
+```csharp
+// ѹ��Ŀ¼��Ĭ�� zip ��ʽ��
+"src".AsDirectory().Compress("src.zip");
+
+// ѹ��Ϊ tar.gz
+"dist".AsDirectory().Compress("dist.tar.gz");
+
+// ������Ŀ¼����
+"project".AsDirectory().Compress("project.zip", true);
+```
+
+### �ļ���ϣУ��
+
+#### VerifyHash
+
+```csharp
+public static Boolean VerifyHash(this FileInfo file, String hash)
+```
+
+��֤�ļ���ϣ�Ƿ�ƥ��Ԥ��ֵ��
+
+**֧�ֵ��㷨**��
+- MD5��16�32�
+- SHA1
+- SHA256
+- SHA512
+- CRC32
+
+**��ϣ��ʽ**��
+- ��ǰ��`md5$abc123...`��`sha256$def456...`��`crc32$12345678`
+- ��ǰ�����ݳ����Զ�ʶ��
+ - 8 �ַ���CRC32
+ - 16/32 �ַ���MD5
+ - 40 �ַ���SHA1
+ - 64 �ַ���SHA256
+ - 128 �ַ���SHA512
+
+**ʾ��**��
+```csharp
+var file = "app.exe".AsFile();
+
+// ���㷨ǰ
+file.VerifyHash("md5$d41d8cd98f00b204e9800998ecf8427e")
+file.VerifyHash("sha256$e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
+file.VerifyHash("crc32$00000000")
+
+// ��ǰ���Զ�ʶ��
+file.VerifyHash("d41d8cd98f00b204e9800998ecf8427e") // 32λ -> MD5
+file.VerifyHash("d41d8cd98f00b204") // 16λ -> MD5��ǰ8�ֽڣ�
+file.VerifyHash("12345678") // 8λ -> CRC32
+```
+
+## ʹ�ó���
+
+### 1. ���������
+
+```csharp
+public class ConfigManager
+{
+ public T Load<T>(String configName) where T : new()
+ {
+ var path = $"config/{configName}.json".GetFullPath();
+ path.EnsureDirectory(true);
+
+ if (File.Exists(path))
+ {
+ var json = File.ReadAllText(path);
+ return JsonSerializer.Deserialize<T>(json) ?? new T();
+ }
+
+ return new T();
+ }
+}
+```
+
+### 2. ��־Ŀ¼����
+
+```csharp
+public class LogManager
+{
+ public String GetLogPath()
+ {
+ var today = DateTime.Today;
+ var path = $"logs/{today:yyyy}/{today:MM}/{today:dd}/".GetBasePath();
+ path.EnsureDirectory(false);
+ return path;
+ }
+}
+```
+
+### 3. ������������
+
+```csharp
+public class UpdateManager
+{
+ public async Task<Boolean> UpdateAsync(String url, String expectedHash)
+ {
+ var tempFile = Path.GetTempFileName();
+
+ // �����ļ�
+ await DownloadAsync(url, tempFile);
+
+ // У���ϣ
+ if (!tempFile.AsFile().VerifyHash(expectedHash))
+ {
+ File.Delete(tempFile);
+ return false;
+ }
+
+ // ��ѹ����
+ tempFile.AsFile().Extract("update_temp", overwrite: true);
+
+ return true;
+ }
+}
+```
+
+### 4. ��Ŀ����
+
+```csharp
+public class Deployer
+{
+ public void Deploy(String sourceDir, String targetDir)
+ {
+ var source = sourceDir.AsDirectory();
+
+ // �������и��µ��ļ�
+ var updated = source.CopyToIfNewer(targetDir, "*.dll;*.exe;*.json", true, name =>
+ {
+ Console.WriteLine($"����: {name}");
+ });
+
+ Console.WriteLine($"������ {updated.Length} ���ļ�");
+
+ // ѹ������
+ targetDir.AsDirectory().Compress($"backup_{DateTime.Now:yyyyMMdd}.zip");
+ }
+}
+```
+
+## ���ʵ��
+
+### 1. ʼ��ʹ�� GetFullPath ����·��
+
+```csharp
+// �Ƽ���ʹ����չ������ȡ����·��
+var path = "config/app.json".GetFullPath();
+
+// ���Ƽ���ֱ��ʹ�����·��
+var path = "config/app.json"; // �����ڲ�ͬ��������Ϊ��һ��
+```
+
+### 2. �����ļ�ǰȷ��Ŀ¼����
+
+```csharp
+// �Ƽ�����ȷ��Ŀ¼����
+var path = "logs/2024/01/app.log".GetFullPath();
+path.EnsureDirectory(true);
+File.WriteAllText(path, content);
+
+// ���Ƽ��������׳� DirectoryNotFoundException
+File.WriteAllText("logs/2024/01/app.log", content);
+```
+
+### 3. ʹ�� AsFile/AsDirectory ��ʽ����
+
+```csharp
+// ������ʽ����
+var size = "data.bin".AsFile().ReadBytes().Length;
+var files = "src".AsDirectory().GetAllFiles("*.cs", true).Count();
+```
+
+## ƽ̨����
+
+| ���� | Windows | Linux |
+|------|---------|-------|
+| ·���ָ��� | `\` | `/` |
+| 7z ѹ�� | ? ֧�� | ? ��֧�� |
+| tar.gz ѹ�� | .NET 7+ ԭ��֧�� | .NET 7+ ԭ��֧�� |
+
+## �������
+
+- [������չ IOHelper](io_helper-������չIOHelper.md)
+- [ѹ����ѹ��](compression-ѹ����ѹ��.md)
+- [��ȫ��չ SecurityHelper](security_helper-��ȫ��չSecurityHelper.md)
diff --git "a/Doc/\350\275\273\351\207\217\347\272\247\345\272\224\347\224\250\344\270\273\346\234\272Host.md" "b/Doc/\350\275\273\351\207\217\347\272\247\345\272\224\347\224\250\344\270\273\346\234\272Host.md"
new file mode 100644
index 0000000..331de70
--- /dev/null
+++ "b/Doc/\350\275\273\351\207\217\347\272\247\345\272\224\347\224\250\344\270\273\346\234\272Host.md"
@@ -0,0 +1,541 @@
+# ������Ӧ������ Host
+
+## ����
+
+`Host` �� NewLife.Core �е�������Ӧ���������ṩӦ�ó����������ڹ������ܡ�֧���йܶ����̨�����Զ�����������ֹͣ�������˳��ȳ������ر��ʺϿ���̨Ӧ�á���̨��������ȳ�����
+
+**�����ռ�**��`NewLife.Model`
+**�ĵ���ַ**��https://newlifex.com/core/host
+
+## ��������
+
+- **�����й�**��֧��ע�������� `IHostedService` ����
+- **�������ڹ���**���Զ�����������ֹͣ���쳣�ع�
+- **�����˳�**����Ӧ Ctrl+C��SIGINT��SIGTERM ��ϵͳ�ź�
+- **��ƽ̨**��֧�� Windows��Linux��macOS
+- **����ע��**���� `ObjectContainer` ��ȼ���
+- **��ʱ����**��֧�������������ʱ��
+
+## ���ٿ�ʼ
+
+```csharp
+using NewLife.Model;
+
+// ��������
+var host = new Host(ObjectContainer.Provider);
+
+// ���Ӻ�̨����
+host.Add<MyBackgroundService>();
+host.Add<AnotherService>();
+
+// ���У�����ֱ���յ��˳��źţ�
+host.Run();
+```
+
+## API �ο�
+
+### IHostedService �ӿ�
+
+��̨�������ʵ�ִ˽ӿڣ�
+
+```csharp
+public interface IHostedService
+{
+ /// <summary>��ʼ����</summary>
+ Task StartAsync(CancellationToken cancellationToken);
+
+ /// <summary>ֹͣ����</summary>
+ Task StopAsync(CancellationToken cancellationToken);
+}
+```
+
+**ʵ��ʾ��**��
+```csharp
+public class MyBackgroundService : IHostedService
+{
+ private CancellationTokenSource? _cts;
+ private Task? _task;
+
+ public Task StartAsync(CancellationToken cancellationToken)
+ {
+ XTrace.WriteLine("MyBackgroundService ����");
+
+ _cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
+ _task = ExecuteAsync(_cts.Token);
+
+ return Task.CompletedTask;
+ }
+
+ public async Task StopAsync(CancellationToken cancellationToken)
+ {
+ XTrace.WriteLine("MyBackgroundService ֹͣ");
+
+ _cts?.Cancel();
+
+ if (_task != null)
+ await Task.WhenAny(_task, Task.Delay(5000, cancellationToken));
+ }
+
+ private async Task ExecuteAsync(CancellationToken stoppingToken)
+ {
+ while (!stoppingToken.IsCancellationRequested)
+ {
+ // ִ�к�̨����
+ XTrace.WriteLine("��̨����ִ����...");
+ await Task.Delay(1000, stoppingToken);
+ }
+ }
+}
+```
+
+### Host ��
+
+#### ���캯��
+
+```csharp
+public Host(IServiceProvider serviceProvider)
+```
+
+ͨ�������ṩ�ߴ�������ʵ����
+
+**ʾ��**��
+```csharp
+// ʹ��ȫ������
+var host = new Host(ObjectContainer.Provider);
+
+// ʹ���Զ�������
+var ioc = new ObjectContainer();
+ioc.AddSingleton<ILogger, ConsoleLogger>();
+var host = new Host(ioc.BuildServiceProvider());
+```
+
+#### Add - ���ӷ���
+
+```csharp
+// ���ӷ�������
+void Add<TService>() where TService : class, IHostedService
+
+// ���ӷ���ʵ��
+void Add(IHostedService service)
+```
+
+**ʾ��**��
+```csharp
+var host = new Host(ObjectContainer.Provider);
+
+// ͨ����������
+host.Add<MyBackgroundService>();
+host.Add<DataSyncService>();
+
+// ͨ��ʵ������
+var service = new CustomService(config);
+host.Add(service);
+```
+
+#### Run / RunAsync - ��������
+
+```csharp
+// ͬ�����У�������
+void Run()
+
+// �첽����
+Task RunAsync()
+```
+
+�����������������з���Ȼ�������ȴ��˳��źš�
+
+**ʾ��**��
+```csharp
+// ͬ������
+host.Run();
+
+// �첽����
+await host.RunAsync();
+
+// �첽���к������������
+_ = host.RunAsync();
+// ��������...
+```
+
+#### StartAsync / StopAsync
+
+```csharp
+Task StartAsync(CancellationToken cancellationToken)
+Task StopAsync(CancellationToken cancellationToken)
+```
+
+�ֶ�����������ֹͣ��
+
+**ʾ��**��
+```csharp
+using var cts = new CancellationTokenSource();
+
+// ��������
+await host.StartAsync(cts.Token);
+
+// ��һЩ����...
+await Task.Delay(10000);
+
+// �ֶ�ֹͣ
+await host.StopAsync(cts.Token);
+```
+
+#### Close - �ر�����
+
+```csharp
+void Close(String? reason)
+```
+
+�����ر�����������ֹͣ���̡�
+
+**ʾ��**��
+```csharp
+// ij�����������ر�
+if (shouldShutdown)
+{
+ host.Close("���������ر�");
+}
+```
+
+#### MaxTime ����
+
+```csharp
+public Int32 MaxTime { get; set; } = -1;
+```
+
+���ִ��ʱ�䣨���룩��Ĭ�� -1 ��ʾ�������С�
+
+**ʾ��**��
+```csharp
+var host = new Host(ObjectContainer.Provider);
+host.MaxTime = 60_000; // �������60��
+host.Add<MyService>();
+host.Run(); // 60����Զ�ֹͣ
+```
+
+### ��̬����
+
+#### RegisterExit - ע���˳��¼�
+
+```csharp
+// ���ܱ���ε���
+static void RegisterExit(EventHandler onExit)
+
+// ��ִ��һ��
+static void RegisterExit(Action onExit)
+```
+
+ע��Ӧ���˳�ʱ�Ļص�������
+
+**ʾ��**��
+```csharp
+// ע���˳���������
+Host.RegisterExit(() =>
+{
+ XTrace.WriteLine("Ӧ�������˳���ִ������...");
+ CleanupResources();
+});
+
+// �������Ļص�
+Host.RegisterExit((sender, e) =>
+{
+ XTrace.WriteLine($"�յ��˳��ź�: {sender}");
+});
+```
+
+## ��������
+
+### AddHostedService ��չ����
+
+```csharp
+// ͨ������ע��
+IObjectContainer AddHostedService<THostedService>()
+
+// ͨ������ע��
+IObjectContainer AddHostedService<THostedService>(
+ Func<IServiceProvider, THostedService> factory)
+```
+
+**ʾ��**��
+```csharp
+var ioc = ObjectContainer.Current;
+
+// ע���̨����
+ioc.AddHostedService<MyBackgroundService>();
+ioc.AddHostedService<DataSyncService>();
+
+// ʹ�ù���
+ioc.AddHostedService(sp =>
+{
+ var config = sp.GetRequiredService<AppConfig>();
+ return new ConfigurableService(config);
+});
+
+// ��������������
+var host = new Host(ioc.BuildServiceProvider());
+host.Run();
+```
+
+## ʹ�ó���
+
+### 1. ��̨����
+
+```csharp
+class Program
+{
+ static void Main()
+ {
+ var ioc = ObjectContainer.Current;
+ ioc.AddHostedService<WorkerService>();
+
+ var host = new Host(ioc.BuildServiceProvider());
+ host.Run();
+ }
+}
+
+public class WorkerService : IHostedService
+{
+ private Timer? _timer;
+
+ public Task StartAsync(CancellationToken cancellationToken)
+ {
+ _timer = new Timer(DoWork, null, 0, 5000);
+ return Task.CompletedTask;
+ }
+
+ public Task StopAsync(CancellationToken cancellationToken)
+ {
+ _timer?.Dispose();
+ return Task.CompletedTask;
+ }
+
+ private void DoWork(Object? state)
+ {
+ XTrace.WriteLine($"������... {DateTime.Now}");
+ }
+}
+```
+
+### 2. �������
+
+```csharp
+class Program
+{
+ static void Main()
+ {
+ var ioc = ObjectContainer.Current;
+
+ // ע�Ṳ������
+ ioc.AddSingleton<IMessageQueue, RedisMessageQueue>();
+ ioc.AddSingleton<ILogger, FileLogger>();
+
+ // ע������̨����
+ ioc.AddHostedService<MessageConsumerService>();
+ ioc.AddHostedService<HealthCheckService>();
+ ioc.AddHostedService<MetricsCollectorService>();
+
+ var host = new Host(ioc.BuildServiceProvider());
+ host.Run();
+ }
+}
+```
+
+### 3. ��ʱ�������
+
+```csharp
+public class ScheduledTaskService : IHostedService
+{
+ private readonly ILogger _logger;
+ private TimerX? _timer;
+
+ public ScheduledTaskService(ILogger logger)
+ {
+ _logger = logger;
+ }
+
+ public Task StartAsync(CancellationToken cancellationToken)
+ {
+ // ÿ���賿2��ִ��
+ _timer = new TimerX(ExecuteTask, null, "0 0 2 * * *");
+ _logger.Info("��ʱ�������������");
+ return Task.CompletedTask;
+ }
+
+ public Task StopAsync(CancellationToken cancellationToken)
+ {
+ _timer?.Dispose();
+ _logger.Info("��ʱ���������ֹͣ");
+ return Task.CompletedTask;
+ }
+
+ private void ExecuteTask(Object? state)
+ {
+ _logger.Info("ִ�ж�ʱ����...");
+ // ������
+ }
+}
+```
+
+### 4. ����ʱ�IJ�������
+
+```csharp
+class Program
+{
+ static async Task Main()
+ {
+ var ioc = ObjectContainer.Current;
+ ioc.AddHostedService<TestService>();
+
+ var host = new Host(ioc.BuildServiceProvider());
+ host.MaxTime = 30_000; // 30����Զ�ֹͣ
+
+ await host.RunAsync();
+
+ Console.WriteLine("�������");
+ }
+}
+```
+
+### 5. �����˳�����
+
+```csharp
+public class GracefulService : IHostedService
+{
+ private readonly List<Task> _runningTasks = new();
+ private CancellationTokenSource? _cts;
+
+ public Task StartAsync(CancellationToken cancellationToken)
+ {
+ _cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
+
+ // ���������������
+ for (var i = 0; i < 5; i++)
+ {
+ _runningTasks.Add(WorkerLoop(i, _cts.Token));
+ }
+
+ return Task.CompletedTask;
+ }
+
+ public async Task StopAsync(CancellationToken cancellationToken)
+ {
+ XTrace.WriteLine("�յ�ֹͣ�źţ��ȴ��������...");
+
+ // ȡ����������
+ _cts?.Cancel();
+
+ // �ȴ�����������ɣ����ȴ�10��
+ var timeout = Task.Delay(10_000, cancellationToken);
+ var allTasks = Task.WhenAll(_runningTasks);
+
+ await Task.WhenAny(allTasks, timeout);
+
+ XTrace.WriteLine("����������ֹͣ");
+ }
+
+ private async Task WorkerLoop(Int32 id, CancellationToken token)
+ {
+ while (!token.IsCancellationRequested)
+ {
+ XTrace.WriteLine($"Worker {id} ִ����...");
+ await Task.Delay(1000, token).ConfigureAwait(false);
+ }
+ }
+}
+```
+
+## �˳��źŴ���
+
+Host �Զ����������˳��źţ�
+
+| �ź� | ƽ̨ | ˵�� |
+|------|------|------|
+| Ctrl+C | ȫƽ̨ | ����̨�ж� |
+| SIGINT | Linux/macOS | �ж��ź� |
+| SIGTERM | Linux/macOS | ��ֹ�źţ�Docker Ĭ�ϣ� |
+| SIGQUIT | Linux/macOS | �˳��ź� |
+| ProcessExit | ȫƽ̨ | �����˳��¼� |
+
+**Docker ����ע��**��
+```dockerfile
+# ʹ�� exec ��ʽ��ȷ���ź���ȷ����
+CMD ["dotnet", "MyApp.dll"]
+
+# ����ʹ�� tini ��Ϊ init ����
+ENTRYPOINT ["/sbin/tini", "--"]
+CMD ["dotnet", "MyApp.dll"]
+```
+
+## ���ʵ��
+
+### 1. ��������˳��
+
+����ע��˳��������������˳��ֹͣ��
+
+```csharp
+ioc.AddHostedService<DatabaseService>(); // ����������ֹͣ
+ioc.AddHostedService<CacheService>(); // �ڶ�
+ioc.AddHostedService<ApiService>(); // ����������ֹͣ
+```
+
+### 2. �쳣����
+
+����ʧ��ʱ���Զ��ع��������ķ���
+
+```csharp
+public class MyService : IHostedService
+{
+ public async Task StartAsync(CancellationToken cancellationToken)
+ {
+ // ����׳��쳣���������ķ���ᱻ�Զ�ֹͣ
+ await InitializeAsync();
+ }
+
+ public Task StopAsync(CancellationToken cancellationToken)
+ {
+ // ȷ��ֹͣ�����׳��쳣
+ try
+ {
+ return CleanupAsync();
+ }
+ catch (Exception ex)
+ {
+ XTrace.WriteException(ex);
+ return Task.CompletedTask;
+ }
+ }
+}
+```
+
+### 3. ��Դ�ͷ�
+
+ʵ�� `IDisposable` ���ж���������
+
+```csharp
+public class ResourceService : IHostedService, IDisposable
+{
+ private FileStream? _file;
+
+ public Task StartAsync(CancellationToken cancellationToken)
+ {
+ _file = File.OpenWrite("data.log");
+ return Task.CompletedTask;
+ }
+
+ public Task StopAsync(CancellationToken cancellationToken)
+ {
+ return Task.CompletedTask;
+ }
+
+ public void Dispose()
+ {
+ _file?.Dispose();
+ }
+}
+```
+
+## �������
+
+- [�������� ObjectContainer](object_container-��������ObjectContainer.md)
+- [����ʱ�� TimerX](timerx-����ʱ��TimerX.md)
+- [��־ϵͳ ILog](log-��־ILog.md)
diff --git "a/Doc/\350\277\220\350\241\214\346\227\266\344\277\241\346\201\257Runtime.md" "b/Doc/\350\277\220\350\241\214\346\227\266\344\277\241\346\201\257Runtime.md"
new file mode 100644
index 0000000..6662fb7
--- /dev/null
+++ "b/Doc/\350\277\220\350\241\214\346\227\266\344\277\241\346\201\257Runtime.md"
@@ -0,0 +1,523 @@
+# ����ʱ��Ϣ Runtime
+
+## ����
+
+`Runtime` �� NewLife.Core �е�����ʱ��Ϣ�����࣬�ṩ��ǰ���л����ĸ��ּ��Ͳ������ܡ���������ϵͳ�жϡ�����������ȡ���ڴ������������Ϣ�ȹ��ܣ��ǿ�ƽ̨��������Ҫ���������
+
+**�����ռ�**��`NewLife`
+**�ĵ���ַ**��https://newlifex.com/core/runtime
+
+## ��������
+
+- **ƽ̨���**��Windows��Linux��OSX��Mono��Unity �����л���ʶ��
+- **�����ж�**������̨��Web��������Ӧ�����ͼ��
+- **�߾��ȼ�ʱ**����ƽ̨�� `TickCount64` ʵ�֣����� 32 λ���
+- **�ڴ����**��GC ���պ������ͷ�
+- **��������**�������ִ�Сд�Ļ���������ȡ
+
+## ���ٿ�ʼ
+
+```csharp
+using NewLife;
+
+// �жϲ���ϵͳ
+if (Runtime.Windows)
+ Console.WriteLine("������ Windows ϵͳ��");
+else if (Runtime.Linux)
+ Console.WriteLine("������ Linux ϵͳ��");
+
+// ������
+if (Runtime.IsConsole)
+ Console.WriteLine("����̨Ӧ��");
+if (Runtime.Container)
+ Console.WriteLine("������������");
+
+// ��ȡϵͳ����ʱ�䣨���룩
+var uptime = Runtime.TickCount64;
+Console.WriteLine($"ϵͳ������ {uptime / 1000 / 60} ����");
+
+// ��ȡ��ǰ����ID
+var pid = Runtime.ProcessId;
+Console.WriteLine($"��ǰ����ID: {pid}");
+
+// �ͷ��ڴ�
+Runtime.FreeMemory();
+```
+
+## API �ο�
+
+### ƽ̨���
+
+#### Windows
+
+```csharp
+public static Boolean Windows { get; }
+```
+
+�Ƿ� Windows ����ϵͳ��
+
+**ʵ�ַ�ʽ**��
+- .NET Core/.NET 5+��ʹ�� `RuntimeInformation.IsOSPlatform(OSPlatform.Windows)`
+- .NET Framework����� `Environment.OSVersion.Platform`
+
+**ʾ��**��
+```csharp
+if (Runtime.Windows)
+{
+ // Windows ���еIJ���������� Win32 API
+ Console.WriteLine("Windows �汾: " + Environment.OSVersion.VersionString);
+}
+```
+
+#### Linux
+
+```csharp
+public static Boolean Linux { get; }
+```
+
+�Ƿ� Linux ����ϵͳ��
+
+**ʾ��**��
+```csharp
+if (Runtime.Linux)
+{
+ // Linux ���еIJ��������ȡ /proc �ļ�ϵͳ
+ var cpuInfo = File.ReadAllText("/proc/cpuinfo");
+}
+```
+
+#### OSX
+
+```csharp
+public static Boolean OSX { get; }
+```
+
+�Ƿ� macOS ����ϵͳ��
+
+#### Mono
+
+```csharp
+public static Boolean Mono { get; }
+```
+
+�Ƿ��� Mono ����ʱ���������С�ͨ����� `Mono.Runtime` �����Ƿ�������жϡ�
+
+**Ӧ�ó���**��
+- ijЩ API �� Mono ����Ϊ��ͬ
+- ��� Mono ���������Ż�����ݴ���
+
+#### Unity
+
+```csharp
+public static Boolean Unity { get; }
+```
+
+�Ƿ��� Unity ���滷�������С�ͨ����� `UnityEngine.Application` �����Ƿ�������жϡ�
+
+### �����ж�
+
+#### IsConsole
+
+```csharp
+public static Boolean IsConsole { get; set; }
+```
+
+�Ƿ����̨Ӧ�ó���
+
+**���**��
+1. ���Է��� `Console.ForegroundColor` ��������̨�����Լ��
+2. ��鵱ǰ�����Ƿ��������ھ��
+3. �κ��쳣����Ϊ�ǿ���̨����
+
+**ʾ��**��
+```csharp
+if (Runtime.IsConsole)
+{
+ Console.WriteLine("���ǿ���̨Ӧ�ã�����ʹ�ò�ɫ���");
+ Console.ForegroundColor = ConsoleColor.Green;
+ Console.WriteLine("��ɫ�ı�");
+ Console.ResetColor();
+}
+else
+{
+ // GUI Ӧ�û����
+ Debug.WriteLine("�ǿ���̨����");
+}
+```
+
+> **ע��**������ͨ������ `Runtime.IsConsole = false` ǿ�ƽ��ÿ���̨�жϡ�
+
+#### Container
+
+```csharp
+public static Boolean Container { get; }
+```
+
+�Ƿ��� Docker/Kubernetes ���������С�ͨ����黷������ `DOTNET_RUNNING_IN_CONTAINER` ���жϡ�
+
+**ʾ��**��
+```csharp
+if (Runtime.Container)
+{
+ // ���������µ������
+ // ���磺ʹ�������ڵ�����·��
+ var configPath = "/app/config";
+}
+```
+
+#### IsWeb
+
+```csharp
+public static Boolean IsWeb { get; }
+```
+
+�Ƿ� Web Ӧ�ó���
+
+**���**��
+- .NET Core/.NET 5+������Ƿ������ `Microsoft.AspNetCore` ����
+- .NET Framework����� `System.Web.HttpRuntime.AppDomainAppId` �Ƿ���ֵ
+
+**ʾ��**��
+```csharp
+if (Runtime.IsWeb)
+{
+ // Web Ӧ�����еĴ���
+ // ���磺ʹ�� HTTP ��������ع���
+}
+```
+
+### ʱ�������
+
+#### TickCount64
+
+```csharp
+public static Int64 TickCount64 { get; }
+```
+
+ϵͳ���������ĺ�������64λ�������ᷢ�� 32 λ������⡣
+
+**ʵ�ַ�ʽ**��
+- .NET Core 3.1+��ֱ��ʹ�� `Environment.TickCount64`
+- Windows �ɿ�ܣ����� `GetTickCount64` Win32 API
+- ����ƽ̨��ʹ�� `Stopwatch.GetTimestamp()` ���㣬����˵� `Environment.TickCount`
+
+**Ӧ�ó���**��
+- �߾��ȼ�ʱ
+- ����ʱ����
+- ���� `Environment.TickCount` Լ 49.7 �����������
+
+**ʾ��**��
+```csharp
+// ����������ʱ
+var start = Runtime.TickCount64;
+DoSomeWork();
+var elapsed = Runtime.TickCount64 - start;
+Console.WriteLine($"��ʱ: {elapsed} ms");
+
+// ���ó�ʱ
+var timeout = Runtime.TickCount64 + 5000; // 5���ʱ
+while (Runtime.TickCount64 < timeout)
+{
+ if (CheckCondition()) break;
+ Thread.Sleep(100);
+}
+```
+
+#### UtcNow
+
+```csharp
+public static DateTimeOffset UtcNow { get; }
+```
+
+��ȡ��ǰ UTC ʱ�䡣����ȫ��ʱ���ṩ�ߣ�`TimerScheduler.GlobalTimeProvider`�������dz�Ӧ���л����η�����ʱ��
+
+**ʾ��**��
+```csharp
+var utcNow = Runtime.UtcNow;
+Console.WriteLine($"UTCʱ��: {utcNow}");
+Console.WriteLine($"����ʱ��: {utcNow.LocalDateTime}");
+```
+
+### ������Ϣ
+
+#### ProcessId
+
+```csharp
+public static Int32 ProcessId { get; }
+```
+
+��ǰ���� ID��ʹ�û�������ظ���ȡ��
+
+**ʵ�ַ�ʽ**��
+- .NET 5+��ʹ�� `Environment.ProcessId`
+- �ɿ�ܣ�ʹ�� `Process.GetCurrentProcess().Id`
+
+**ʾ��**��
+```csharp
+Console.WriteLine($"��ǰ����ID: {Runtime.ProcessId}");
+
+// ������־��¼
+var logPrefix = $"[PID:{Runtime.ProcessId}]";
+```
+
+#### ClientId
+
+```csharp
+public static String ClientId { get; }
+```
+
+�ͻ��˱�ʶ����ʽΪ `ip@pid`�����ڷֲ�ʽϵͳ�б�ʶ�ͻ���ʵ����
+
+**ʾ��**��
+```csharp
+Console.WriteLine($"�ͻ��˱�ʶ: {Runtime.ClientId}");
+// �������: 192.168.1.100@12345
+
+// ���ڷֲ�ʽ������Ϣ���������߱�ʶ��
+var consumerId = Runtime.ClientId;
+```
+
+### ��������
+
+#### GetEnvironmentVariable
+
+```csharp
+public static String? GetEnvironmentVariable(String variable)
+```
+
+��ȡ����������**�����ִ�Сд**��
+
+**�ص�**��
+- �ȳ��Ծ�ȷƥ��
+- ��δ�ҵ����������л����������в����ִ�Сд�ıȽ�
+
+**ʾ��**��
+```csharp
+// �����ִ�Сд��ȡ��������
+var path = Runtime.GetEnvironmentVariable("PATH");
+var home = Runtime.GetEnvironmentVariable("HOME");
+var customVar = Runtime.GetEnvironmentVariable("MY_APP_CONFIG");
+```
+
+#### GetEnvironmentVariables
+
+```csharp
+public static IDictionary<String, String?> GetEnvironmentVariables()
+```
+
+��ȡ���л������������ز����ִ�Сд���ֵ䡣
+
+**ʾ��**��
+```csharp
+var envVars = Runtime.GetEnvironmentVariables();
+foreach (var kv in envVars.Where(e => e.Key.StartsWith("DOTNET")))
+{
+ Console.WriteLine($"{kv.Key} = {kv.Value}");
+}
+```
+
+### ����
+
+#### CreateConfigOnMissing
+
+```csharp
+public static Boolean CreateConfigOnMissing { get; set; }
+```
+
+�����ļ�������ʱ���Ƿ�����Ĭ�������ļ���Ĭ��Ϊ `true`��
+
+**���÷�ʽ**��
+- ����������`CreateConfigOnMissing=false`
+- �������ã�`Runtime.CreateConfigOnMissing = false`
+
+**ʾ��**��
+```csharp
+// ����������ֹ�Զ����������ļ�
+Runtime.CreateConfigOnMissing = false;
+```
+
+### �ڴ����
+
+#### FreeMemory
+
+```csharp
+public static Boolean FreeMemory(Int32 processId = 0, Boolean gc = true, Boolean workingSet = true)
+```
+
+�ͷ��ڴ档ִ�� GC ���ղ��ͷŹ�������Windows����
+
+**����˵��**��
+- `processId`��Ŀ�����ID��0 ��ʾ��ǰ����
+- `gc`���Ƿ�ִ�� GC ���գ�����ǰ������Ч��
+- `workingSet`���Ƿ��ͷŹ��������� Windows ��Ч��
+
+**ִ�в���**��
+1. ִ�� `GC.Collect` ������������
+2. ���� `GC.WaitForPendingFinalizers` �ȴ��ս���
+3. �ٴ�ִ�� `GC.Collect`
+4. ���� `EmptyWorkingSet` �ͷŹ�������Windows��
+
+**ʾ��**��
+```csharp
+// �����ͷ��ڴ�
+var timer = new TimerX(state =>
+{
+ Runtime.FreeMemory();
+}, null, 60_000, 60_000); // ÿ����ִ��һ��
+
+// ���ͷŹ�������������GC
+Runtime.FreeMemory(gc: false);
+
+// �ͷ�ָ�����̵��ڴ�
+Runtime.FreeMemory(processId: 1234, gc: false);
+```
+
+> **ע��**��Ƶ������ `FreeMemory` ����Ӱ�����ܣ��������ڴ�ѹ���ϴ�ʱ���ڵ��á�
+
+## ʹ�ó���
+
+### 1. ��ƽ̨·������
+
+```csharp
+public String GetConfigPath()
+{
+ if (Runtime.Windows)
+ return @"C:\ProgramData\MyApp\config.json";
+ else if (Runtime.Linux)
+ return "/etc/myapp/config.json";
+ else if (Runtime.OSX)
+ return "/Library/Application Support/MyApp/config.json";
+ else
+ return "config.json";
+}
+```
+
+### 2. ������������
+
+```csharp
+public void ConfigureServices()
+{
+ if (Runtime.Container)
+ {
+ // �����������ӻ���������ȡ����
+ var connStr = Runtime.GetEnvironmentVariable("DATABASE_URL");
+ services.AddDbContext<MyDbContext>(options =>
+ options.UseNpgsql(connStr));
+ }
+ else
+ {
+ // ���ؿ������������ļ���ȡ
+ var connStr = Configuration.GetConnectionString("Default");
+ services.AddDbContext<MyDbContext>(options =>
+ options.UseNpgsql(connStr));
+ }
+}
+```
+
+### 3. �ڴ������ͷ�
+
+```csharp
+public class MemoryMonitor
+{
+ private readonly Timer _timer;
+ private const Int64 MemoryThreshold = 500 * 1024 * 1024; // 500MB
+
+ public MemoryMonitor()
+ {
+ _timer = new Timer(CheckMemory, null, 0, 30_000);
+ }
+
+ private void CheckMemory(Object? state)
+ {
+ var gcMemory = GC.GetTotalMemory(false);
+ if (gcMemory > MemoryThreshold)
+ {
+ XTrace.WriteLine($"�ڴ泬����ֵ ({gcMemory / 1024 / 1024}MB)����ʼ�ͷ�");
+ Runtime.FreeMemory();
+ }
+ }
+}
+```
+
+### 4. ���ܼ�ʱ��
+
+```csharp
+public class PerformanceTimer : IDisposable
+{
+ private readonly String _operation;
+ private readonly Int64 _startTime;
+
+ public PerformanceTimer(String operation)
+ {
+ _operation = operation;
+ _startTime = Runtime.TickCount64;
+ }
+
+ public void Dispose()
+ {
+ var elapsed = Runtime.TickCount64 - _startTime;
+ XTrace.WriteLine($"{_operation} ��ʱ: {elapsed}ms");
+ }
+}
+
+// ʹ��
+using (new PerformanceTimer("���ݿ��ѯ"))
+{
+ var result = db.Query<User>().ToList();
+}
+```
+
+## ���ʵ��
+
+### 1. ƽ̨�ض��������
+
+```csharp
+// �Ƽ���ʹ�������жϸ���ƽ̨�ض�����
+public void DoWork()
+{
+ if (Runtime.Windows)
+ DoWorkWindows();
+ else if (Runtime.Linux)
+ DoWorkLinux();
+ else
+ DoWorkDefault();
+}
+```
+
+### 2. ����Ƶ������ FreeMemory
+
+```csharp
+// ���Ƽ���ÿ�β������ͷ�
+foreach (var item in items)
+{
+ ProcessItem(item);
+ Runtime.FreeMemory(); // ����ɱ�֣�
+}
+
+// �Ƽ��������������ͷţ���ʱ�ͷ�
+foreach (var item in items)
+{
+ ProcessItem(item);
+}
+Runtime.FreeMemory(); // ������ɺ�ͳһ�ͷ�
+```
+
+### 3. ʹ�� TickCount64 ���� DateTime ��ʱ
+
+```csharp
+// ���Ƽ���DateTime ��ʱ������ϵͳʱ�����Ӱ��
+var start = DateTime.Now;
+DoWork();
+var elapsed = (DateTime.Now - start).TotalMilliseconds;
+
+// �Ƽ���TickCount64 ����ϵͳʱ��Ӱ��
+var start = Runtime.TickCount64;
+DoWork();
+var elapsed = Runtime.TickCount64 - start;
+```
+
+## �������
+
+- [������Ϣ MachineInfo](machine_info-������ϢMachineInfo.md)
+- [��־ϵͳ ILog](log-��־ILog.md)
+- [����ʱ�� TimerX](timerx-����ʱ��TimerX.md)
diff --git "a/Doc/\350\277\233\347\250\213\346\211\251\345\261\225ProcessHelper.md" "b/Doc/\350\277\233\347\250\213\346\211\251\345\261\225ProcessHelper.md"
new file mode 100644
index 0000000..afc4e7a
--- /dev/null
+++ "b/Doc/\350\277\233\347\250\213\346\211\251\345\261\225ProcessHelper.md"
@@ -0,0 +1,425 @@
+# ������չ ProcessHelper
+
+## ����
+
+`ProcessHelper` �� NewLife.Core �еĽ��̹��������࣬�ṩ���̲��ҡ����̿��ơ�������ִ�еȹ��ܡ�֧�� Windows �� Linux ˫ƽ̨���ܹ���ȷʶ�� dotnet/java �������̵���ʵ���ơ�
+
+**�����ռ�**��`NewLife`
+**�ĵ���ַ**��https://newlifex.com/core/process_helper
+
+## ��������
+
+- **��ƽ̨֧��**��ͬʱ֧�� Windows �� Linux ϵͳ
+- **��������ʶ��**����ȷʶ�� dotnet/java �йܽ��̵���ʵ������
+- **��ȫ���̿���**���ṩ�º��˳���ǿ����ֹ���ַ�ʽ
+- **������ִ��**��֧��ͬ��/�첽ִ�С��������ʱ����
+
+## ���ٿ�ʼ
+
+```csharp
+using NewLife;
+using System.Diagnostics;
+
+// ��ȡ������ʵ���ƣ�֧�� dotnet/java ������
+var process = Process.GetCurrentProcess();
+var name = process.GetProcessName();
+
+// ִ�������ȡ���
+var output = "ipconfig".Execute("/all");
+
+// �����ش���ִ������
+"notepad.exe".Run("test.txt", 0);
+
+// ��ȫ�˳�����
+process.SafetyKill();
+
+// ǿ����ֹ������
+process.ForceKill();
+```
+
+## API �ο�
+
+### ���̲���
+
+#### GetProcessName
+
+```csharp
+public static String GetProcessName(this Process process)
+```
+
+��ȡ���̵������ơ����� dotnet/java �������̣�����������Ŀ�����/��� Jar ���ƣ�������չ������
+
+**Ӧ�ó���**��
+- ���̼�غ���
+- ������
+- ��־��¼��ʶ����ʵӦ����
+
+**ʾ��**��
+```csharp
+// ��ͨ����
+var notepad = Process.GetProcessesByName("notepad")[0];
+notepad.GetProcessName() // "notepad"
+
+// dotnet �������̣����� MyApp.dll��
+// ������dotnet /path/to/MyApp.dll --arg1 value1
+var dotnetProcess = ...;
+dotnetProcess.GetProcessName() // "MyApp"
+
+// java �������̣����� app.jar��
+// ������java -jar /path/to/app.jar
+var javaProcess = ...;
+javaProcess.GetProcessName() // "app"
+```
+
+#### GetCommandLine
+
+```csharp
+public static String? GetCommandLine(Int32 processId)
+```
+
+��ȡָ�����̵������������ַ�����
+
+**ƽ̨ʵ��**��
+- **Linux**����ȡ `/proc/{pid}/cmdline` �ļ�
+- **Windows**��ͨ�� `NtQueryInformationProcess` ��ȡ���� PEB
+
+**ʾ��**��
+```csharp
+var cmdLine = ProcessHelper.GetCommandLine(1234);
+// Windows: "C:\Program Files\dotnet\dotnet.exe" MyApp.dll --env Production
+// Linux: /usr/bin/dotnet MyApp.dll --env Production
+```
+
+#### GetCommandLineArgs
+
+```csharp
+public static String[]? GetCommandLineArgs(Int32 processId)
+```
+
+��ȡָ�����̵������в������顣
+
+**ʾ��**��
+```csharp
+var args = ProcessHelper.GetCommandLineArgs(1234);
+// ["dotnet", "MyApp.dll", "--env", "Production"]
+```
+
+### ���̿���
+
+#### SafetyKill
+
+```csharp
+public static Process? SafetyKill(this Process process, Int32 msWait = 5_000, Int32 times = 50, Int32 interval = 200)
+```
+
+��ȫ�˳����̣��ºͷ�ʽ��������������ֹ�źţ��ý����л���ִ���������롣
+
+**����˵��**��
+- `msWait`�������źź�ij�ʼ�ȴ�ʱ�䣬Ĭ�� 5000 ����
+- `times`����ѯ��������Ĭ�� 50 ��
+- `interval`����ѯ�����Ĭ�� 200 ����
+
+**ƽ̨ʵ��**��
+- **Linux**������ `kill` �źţ�Ĭ�� SIGTERM��
+- **Windows**��ִ�� `taskkill -pid {id}`
+
+**ʾ��**��
+```csharp
+var process = Process.Start("MyApp.exe");
+
+// �ºرգ��ȴ���� 10 ��
+process.SafetyKill(msWait: 10_000);
+
+// ����Ƿ�ɹ��˳�
+if (!process.GetHasExited())
+{
+ // ����δ�ڹ涨ʱ�����˳���������Ҫǿ����ֹ
+ process.ForceKill();
+}
+```
+
+#### ForceKill
+
+```csharp
+public static Process? ForceKill(this Process process, Int32 msWait = 5_000)
+```
+
+ǿ����ֹ�����������������ӽ��̡�
+
+**ƽ̨ʵ��**��
+- **Linux**������ `kill -9` �źţ�SIGKILL��
+- **Windows**��ִ�� `taskkill /t /f /pid {id}`
+- **.NET Core 3.0+**��ʹ�� `Process.Kill(true)` ��ֹ������
+
+**ʾ��**��
+```csharp
+// ǿ����ֹ���̼��������ӽ���
+process.ForceKill();
+
+// ����ָ�������ĵȴ�ʱ��
+process.ForceKill(msWait: 10_000);
+```
+
+#### GetHasExited
+
+```csharp
+public static Boolean GetHasExited(this Process process)
+```
+
+��ȫ��ȡ�����Ƿ�����ֹ�������̾�����ɷ���ʱ���� `true`����Ϊ���˳�����
+
+**ʾ��**��
+```csharp
+if (process.GetHasExited())
+{
+ Console.WriteLine("�������˳�");
+}
+```
+
+### ������ִ��
+
+#### Run
+
+```csharp
+public static Int32 Run(
+ this String cmd,
+ String? arguments = null,
+ Int32 msWait = 0,
+ Action<String?>? output = null,
+ Action<Process>? onExit = null,
+ String? working = null)
+```
+
+�����ش���ִ�������С�
+
+**����˵��**��
+- `cmd`����ִ���ļ�����·��
+- `arguments`���������
+- `msWait`���ȴ�ʱ�䣨0=���ȴ���<0=���ȴ���>0=��ȴ���������
+- `output`������ص�ί�У��� msWait > 0��
+- `onExit`�������˳��ص�
+- `working`������Ŀ¼
+
+**����ֵ**�������˳����룻δ�ȴ���ʱ���� -1
+
+**ʾ��**��
+```csharp
+// ���ȴ�����ִ̨��
+"notepad.exe".Run("test.txt");
+
+// �ȴ�ִ����ɣ���ȡ�˳���
+var exitCode = "ping".Run("localhost -n 4", 30_000);
+
+// �������
+var output = new StringBuilder();
+"ipconfig".Run("/all", 5_000, line => output.AppendLine(line));
+Console.WriteLine(output.ToString());
+
+// ������Ŀ¼
+"npm".Run("install", 60_000, working: @"C:\Projects\MyApp");
+
+// �����˳�ʱ�ص�
+"MyApp.exe".Run(onExit: p => Console.WriteLine($"�˳���: {p.ExitCode}"));
+```
+
+#### ShellExecute
+
+```csharp
+public static Process ShellExecute(
+ this String fileName,
+ String? arguments = null,
+ String? workingDirectory = null)
+```
+
+�� Shell ��ִ�����Ŀ����̲��ǵ�ǰ���̵��ӽ��̣������汾�����˳���
+
+**Ӧ�ó���**��
+- ���ļ���ʹ��ϵͳĬ�ϳ���
+- �� URL��ʹ��Ĭ���������
+- ��������Ӧ�ó���
+
+**ʾ��**��
+```csharp
+// ��Ĭ�ϳ�����ļ�
+"document.pdf".ShellExecute();
+
+// ��Ĭ�����������ַ
+"https://newlifex.com".ShellExecute();
+
+// �Թ���Ա��������
+// ע�⣺��Ҫ�� ProcessStartInfo ������ Verb = "runas"
+"cmd.exe".ShellExecute("/k echo Hello");
+
+// ָ������Ŀ¼
+"MyApp.exe".ShellExecute("--config app.json", @"C:\Apps");
+```
+
+#### Execute
+
+```csharp
+public static String? Execute(
+ this String cmd,
+ String? arguments = null,
+ Int32 msWait = 0,
+ Boolean returnError = false)
+```
+
+ִ��������ر�������ݡ�
+
+**����˵��**��
+- `msWait`���ȴ�ʱ�䣨0=����ֱ���˳���>0=��ʱ��ǿɱ��
+- `returnError`���ޱ����ʱ�Ƿش������
+
+**ʾ��**��
+```csharp
+// ��ȡ IP ����
+var ipConfig = "ipconfig".Execute("/all");
+
+// ��ȡ Git �汾
+var gitVersion = "git".Execute("--version");
+
+// ִ�� Linux ����
+var diskUsage = "df".Execute("-h");
+
+// ��ʱ����
+var result = "ping".Execute("localhost", 5_000);
+
+// ʧ��ʱ���ش�����Ϣ
+var output = "invalid_cmd".Execute(returnError: true);
+```
+
+## ʹ�ó���
+
+### 1. �������
+
+```csharp
+public class ServiceManager
+{
+ public void StopService(String serviceName)
+ {
+ var processes = Process.GetProcesses()
+ .Where(p => p.GetProcessName().EqualIgnoreCase(serviceName));
+
+ foreach (var process in processes)
+ {
+ // �ȳ����ºر�
+ process.SafetyKill(msWait: 10_000);
+
+ // �����û�˳���ǿ����ֹ
+ if (!process.GetHasExited())
+ {
+ process.ForceKill();
+ }
+ }
+ }
+}
+```
+
+### 2. �ű�ִ��
+
+```csharp
+public class ScriptRunner
+{
+ public String RunPowerShell(String script)
+ {
+ return "powershell".Execute($"-ExecutionPolicy Bypass -Command \"{script}\"", 60_000);
+ }
+
+ public String RunBash(String script)
+ {
+ return "bash".Execute($"-c \"{script}\"", 60_000);
+ }
+}
+```
+
+### 3. ���̼��
+
+```csharp
+public class ProcessMonitor
+{
+ public void Monitor(String appName)
+ {
+ while (true)
+ {
+ var processes = Process.GetProcesses()
+ .Where(p => p.GetProcessName().EqualIgnoreCase(appName))
+ .ToList();
+
+ Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] {appName} ������: {processes.Count}");
+
+ foreach (var p in processes)
+ {
+ var cmdLine = ProcessHelper.GetCommandLine(p.Id);
+ Console.WriteLine($" PID={p.Id}, CommandLine={cmdLine}");
+ }
+
+ Thread.Sleep(5000);
+ }
+ }
+}
+```
+
+## ���ʵ��
+
+### 1. ���Źر�����
+
+```csharp
+// �Ƽ������ºͣ���ǿ��
+public void StopProcess(Process process)
+{
+ // �ºرգ������������Ļ���
+ process.SafetyKill(msWait: 5_000);
+
+ // �����û�˳���ǿ����ֹ
+ if (!process.GetHasExited())
+ {
+ process.ForceKill();
+ }
+}
+```
+
+### 2. �������ó�ʱ
+
+```csharp
+// ���������ص����ó�ʱ
+var quickResult = "echo".Execute("Hello", msWait: 1_000); // ��������
+var longResult = "npm".Execute("install", msWait: 300_000); // ��ʱ����
+```
+
+### 3. ��������ص�
+
+```csharp
+// ʵʱ�����������
+var lines = new List<String>();
+"find".Run("/", 60_000, line =>
+{
+ if (!line.IsNullOrEmpty())
+ {
+ lines.Add(line);
+ if (lines.Count % 1000 == 0)
+ Console.WriteLine($"�Ѵ��� {lines.Count} ��");
+ }
+});
+```
+
+## ƽ̨����
+
+| ���� | Windows | Linux |
+|------|---------|-------|
+| GetCommandLine | NtQueryInformationProcess | /proc/{pid}/cmdline |
+| SafetyKill | taskkill | kill (SIGTERM) |
+| ForceKill | taskkill /f /t | kill -9 (SIGKILL) |
+| ShellExecute | Shell ִ�� | ��Ҫ���� UseShellExecute=true |
+
+## ע������
+
+1. **Ȩ��Ҫ��**�����ֲ���������Ҫ����Ա/root Ȩ��
+2. **��������ֹ**��`ForceKill` ����ֹ�����ӽ��̣������ʹ��
+3. **�����г���**��Windows �����г�������Լ 8191 �ַ�
+4. **��������**��ִ������ʱע��������룬��ͨ�� `Encoding` ����ָ��
+
+## �������
+
+- [����ʱ��Ϣ Runtime](runtime-����ʱ��ϢRuntime.md)
+- [������Ӧ������ Host](host-������Ӧ������Host.md)
+- [������� NewLife.Agent](https://newlifex.com/core/agent)
diff --git "a/Doc/IConfigProvider\344\275\277\347\224\250\350\257\264\346\230\216.md" "b/Doc/\351\205\215\347\275\256\346\217\220\344\276\233\350\200\205IConfigProvider.md"
similarity index 100%
rename from "Doc/IConfigProvider\344\275\277\347\224\250\350\257\264\346\230\216.md"
rename to "Doc/\351\205\215\347\275\256\346\217\220\344\276\233\350\200\205IConfigProvider.md"
diff --git "a/Doc/\351\205\215\347\275\256\347\263\273\347\273\237Config.md" "b/Doc/\351\205\215\347\275\256\347\263\273\347\273\237Config.md"
new file mode 100644
index 0000000..4b4b4d6
--- /dev/null
+++ "b/Doc/\351\205\215\347\275\256\347\263\273\347\273\237Config.md"
@@ -0,0 +1,410 @@
+# ����ϵͳ Config
+
+## ����
+
+NewLife.Core �ṩ��ǿ����������ϵͳ��֧�� XML��JSON��INI �ȶ��ָ�ʽ���Լ������ļ���Զ���������ġ�ͨ�� `Config<T>` ������Կ��ٴ���ǿ�������ã�֧���ȸ��º��Զ����档
+
+**�����ռ�**��`NewLife.Configuration`
+**�ĵ���ַ**��https://newlifex.com/core/config
+
+## ��������
+
+- **ǿ��������**���̳� `Config<T>` �Զ����������ļ�
+- **���ʽ֧��**��XML��JSON��INI��HTTP �������ṩ��
+- **�ȸ���**�������ļ��仯ʱ�Զ�����
+- **ע��֧��**��XML ��ʽ֧���Զ�����ע��
+- **�ֲ�����**��֧�ֶ༶Ƕ�����ýṹ
+- **��������**��֧��Զ���������ģ����dz���
+
+## ���ٿ�ʼ
+
+### ����������
+
+```csharp
+using NewLife.Configuration;
+using System.ComponentModel;
+
+/// <summary>Ӧ������</summary>
+[Config("App")] // �����ļ���Ϊ App.config
+public class AppConfig : Config<AppConfig>
+{
+ [Description("Ӧ������")]
+ public String Name { get; set; } = "MyApp";
+
+ [Description("����˿�")]
+ public Int32 Port { get; set; } = 8080;
+
+ [Description("����ģʽ")]
+ public Boolean Debug { get; set; }
+
+ [Description("���ݿ�����")]
+ public String ConnectionString { get; set; } = "Server=.;Database=test";
+}
+```
+
+### ʹ������
+
+```csharp
+// ��ȡ���ã��Զ�����/���������ļ���
+var config = AppConfig.Current;
+
+Console.WriteLine($"Ӧ��: {config.Name}");
+Console.WriteLine($"�˿�: {config.Port}");
+
+// �IJ�����
+config.Debug = true;
+config.Save();
+```
+
+**�Զ����ɵ������ļ�** (`App.config`)��
+```xml
+<?xml version="1.0" encoding="utf-8"?>
+<App>
+ <!--Ӧ������-->
+ <Name>MyApp</Name>
+ <!--����˿�-->
+ <Port>8080</Port>
+ <!--����ģʽ-->
+ <Debug>false</Debug>
+ <!--���ݿ�����-->
+ <ConnectionString>Server=.;Database=test</ConnectionString>
+</App>
+```
+
+## API �ο�
+
+### Config<T> ����
+
+```csharp
+public class Config<TConfig> where TConfig : Config<TConfig>, new()
+{
+ /// <summary>��ǰʹ�õ��ṩ��</summary>
+ public static IConfigProvider? Provider { get; set; }
+
+ /// <summary>��ǰʵ��</summary>
+ public static TConfig Current { get; }
+
+ /// <summary>��������</summary>
+ public virtual Boolean Load();
+
+ /// <summary>��������</summary>
+ public virtual Boolean Save();
+
+ /// <summary>���ü��غ�</summary>
+ protected virtual void OnLoaded() { }
+}
+```
+
+### ConfigAttribute ����
+
+```csharp
+[AttributeUsage(AttributeTargets.Class)]
+public class ConfigAttribute : Attribute
+{
+ /// <summary>���������ļ�����������չ����</summary>
+ public String Name { get; set; }
+
+ /// <summary>�����ṩ������</summary>
+ public Type? Provider { get; set; }
+}
+```
+
+### IConfigProvider �ӿ�
+
+```csharp
+public interface IConfigProvider
+{
+ /// <summary>����</summary>
+ String Name { get; set; }
+
+ /// <summary>��Ԫ��</summary>
+ IConfigSection Root { get; set; }
+
+ /// <summary>�Ƿ�������</summary>
+ Boolean IsNew { get; set; }
+
+ /// <summary>��ȡ/��������ֵ</summary>
+ String? this[String key] { get; set; }
+
+ /// <summary>��������</summary>
+ Boolean LoadAll();
+
+ /// <summary>��������</summary>
+ Boolean SaveAll();
+
+ /// <summary>���ص�ģ��</summary>
+ T? Load<T>(String? path = null) where T : new();
+
+ /// <summary>��ģ�ͣ��ȸ��£�</summary>
+ void Bind<T>(T model, Boolean autoReload = true, String? path = null);
+
+ /// <summary>���øı��¼�</summary>
+ event EventHandler? Changed;
+}
+```
+
+## �����ṩ��
+
+### XmlConfigProvider��Ĭ�ϣ�
+
+```csharp
+// �Զ�ʹ�� XML ��ʽ
+[Config("Database")]
+public class DbConfig : Config<DbConfig> { }
+
+// ����ʽָ��
+[Config("Database", Provider = typeof(XmlConfigProvider))]
+public class DbConfig : Config<DbConfig> { }
+```
+
+### JsonConfigProvider
+
+```csharp
+[Config("appsettings", Provider = typeof(JsonConfigProvider))]
+public class AppSettings : Config<AppSettings>
+{
+ public String Name { get; set; }
+ public LoggingConfig Logging { get; set; } = new();
+}
+
+public class LoggingConfig
+{
+ public String Level { get; set; } = "Information";
+ public Boolean Console { get; set; } = true;
+}
+```
+
+**���ɵ� JSON �ļ�**��
+```json
+{
+ "Name": "MyApp",
+ "Logging": {
+ "Level": "Information",
+ "Console": true
+ }
+}
+```
+
+### InIConfigProvider
+
+```csharp
+[Config("settings", Provider = typeof(InIConfigProvider))]
+public class IniConfig : Config<IniConfig>
+{
+ public String Server { get; set; }
+ public Int32 Port { get; set; }
+}
+```
+
+### HttpConfigProvider
+
+��������Զ���������ģ�
+
+```csharp
+[HttpConfig("http://config.server.com", AppId = "myapp", Secret = "xxx")]
+public class RemoteConfig : Config<RemoteConfig>
+{
+ public String Setting1 { get; set; }
+}
+```
+
+## ʹ�ó���
+
+### 1. ���ݿ�����
+
+```csharp
+[Config("Database")]
+public class DatabaseConfig : Config<DatabaseConfig>
+{
+ [Description("���ݿ�����")]
+ public String DbType { get; set; } = "MySql";
+
+ [Description("�����ַ���")]
+ public String ConnectionString { get; set; }
+
+ [Description("���������")]
+ public Int32 MaxPoolSize { get; set; } = 100;
+
+ [Description("���ʱ���룩")]
+ public Int32 CommandTimeout { get; set; } = 30;
+}
+
+// ʹ��
+var db = DatabaseConfig.Current;
+var connStr = db.ConnectionString;
+```
+
+### 2. Ƕ������
+
+```csharp
+[Config("Service")]
+public class ServiceConfig : Config<ServiceConfig>
+{
+ public String Name { get; set; } = "MyService";
+ public HttpConfig Http { get; set; } = new();
+ public CacheConfig Cache { get; set; } = new();
+}
+
+public class HttpConfig
+{
+ public Int32 Port { get; set; } = 8080;
+ public Int32 Timeout { get; set; } = 30;
+ public Boolean Ssl { get; set; }
+}
+
+public class CacheConfig
+{
+ public String Type { get; set; } = "Memory";
+ public Int32 Expire { get; set; } = 3600;
+}
+```
+
+### 3. ��������
+
+```csharp
+[Config("Servers")]
+public class ServersConfig : Config<ServersConfig>
+{
+ public String[] Hosts { get; set; } = ["localhost"];
+ public List<EndpointConfig> Endpoints { get; set; } = new();
+}
+
+public class EndpointConfig
+{
+ public String Host { get; set; }
+ public Int32 Port { get; set; }
+}
+```
+
+### 4. ������֤
+
+```csharp
+[Config("App")]
+public class AppConfig : Config<AppConfig>
+{
+ public Int32 Port { get; set; } = 8080;
+
+ protected override void OnLoaded()
+ {
+ // ��֤����
+ if (Port <= 0 || Port > 65535)
+ {
+ Port = 8080;
+ XTrace.WriteLine("�˿�������Ч��ʹ��Ĭ��ֵ 8080");
+ }
+ }
+}
+```
+
+### 5. �������
+
+```csharp
+var config = AppConfig.Current;
+AppConfig.Provider.Changed += (s, e) =>
+{
+ XTrace.WriteLine("�����Ѹ���");
+ // ���¶�ȡ����
+ config = AppConfig.Current;
+};
+```
+
+### 6. ֱ��ʹ���ṩ��
+
+```csharp
+// ���̳� Config<T>��ֱ��ʹ���ṩ��
+var provider = new JsonConfigProvider { FileName = "custom.json" };
+provider.LoadAll();
+
+// ��ȡֵ
+var name = provider["Name"];
+var port = provider["Server:Port"].ToInt();
+
+// ����ֵ
+provider["Debug"] = "true";
+provider.SaveAll();
+```
+
+## ��������
+
+Ĭ�������ļ������Ӧ�ó���Ŀ¼����ͨ�����·�ʽ�Զ��壺
+
+```csharp
+// ���·��
+[Config("Config/App")]
+public class AppConfig : Config<AppConfig> { }
+
+// �����ṩ�߳�ʼ��
+var provider = new XmlConfigProvider();
+provider.Init("Config/App.config");
+```
+
+## ���ʵ��
+
+### 1. ʹ�� Description ����
+
+```csharp
+[Description("��־����Debug/Info/Warn/Error")]
+public String LogLevel { get; set; } = "Info";
+```
+
+### 2. �ṩĬ��ֵ
+
+```csharp
+public Int32 MaxRetry { get; set; } = 3;
+public String[] AllowedHosts { get; set; } = ["*"];
+```
+
+### 3. ������Ϣ����
+
+```csharp
+[Config("Secrets")]
+public class SecretsConfig : Config<SecretsConfig>
+{
+ // ����ӻ���������ȡ
+ public String ApiKey { get; set; } =
+ Environment.GetEnvironmentVariable("API_KEY") ?? "";
+}
+```
+
+### 4. ��������
+
+```csharp
+// ǿ�����¼�������
+AppConfig._Current = null;
+var fresh = AppConfig.Current;
+```
+
+## �� appsettings.json ����
+
+```csharp
+// ���� ASP.NET Core ��������
+var provider = JsonConfigProvider.LoadAppSettings();
+var connectionString = provider["ConnectionStrings:Default"];
+var logLevel = provider["Logging:LogLevel:Default"];
+```
+
+## ���ü̳�
+
+```csharp
+public abstract class BaseConfig<T> : Config<T> where T : BaseConfig<T>, new()
+{
+ [Description("Ӧ�ð汾")]
+ public String Version { get; set; } = "1.0.0";
+
+ [Description("���õ���")]
+ public Boolean Debug { get; set; }
+}
+
+[Config("MyApp")]
+public class MyAppConfig : BaseConfig<MyAppConfig>
+{
+ [Description("�ض�����")]
+ public String CustomSetting { get; set; }
+}
+```
+
+## �������
+
+- [JSON ���л�](json-JSON���л�.md)
+- [XML ���л�](xml-XML���л�.md)
+- [��־ϵͳ ILog](log-��־ILog.md)
diff --git "a/Doc/\351\223\276\350\267\257\350\277\275\350\270\252ITracer.md" "b/Doc/\351\223\276\350\267\257\350\277\275\350\270\252ITracer.md"
new file mode 100644
index 0000000..e87e606
--- /dev/null
+++ "b/Doc/\351\223\276\350\267\257\350\277\275\350\270\252ITracer.md"
@@ -0,0 +1,661 @@
+# ��·��ITracer
+
+## ����
+
+�ɹ۲����Ǻ����ִ�Ӧ�������ĺ���ָ��֮һ��NewLife.Core �ṩ��һ����������·�ٹ淶��`ITracer`/`ISpan`������ʵ�������� APM��Application Performance Monitoring����
+
+�봫ͳ APM ϵͳ��ͬ��NewLife ����·�ٲ���**���ز���+ͳ��**�ķ�ʽ��
+- �ڱ���������ݲ����ͳ���ͳ��
+- ���ϱ�ͳ�����ݺ�������������
+- �����ʡ���紫��ʹ洢�ɱ�
+
+NewLife ȫϵ����Ŀ��30+ ������������� `ITracer` ��㣬�����߿��ԣ�
+1. ������ػ�ȡ�������ָ��
+2. �����dz����ƽ̨ʵ�ֲַ�ʽ��
+3. ���ڹ淶��չ�Զ������
+
+**Nuget ��**: `NewLife.Core`
+**Դ��**: [NewLife.Core/Log/ITracer.cs](https://github.com/NewLifeX/X/blob/master/NewLife.Core/Log/ITracer.cs)
+
+---
+
+## ��������
+
+### �����÷�
+
+������ʾ����
+
+```csharp
+using var span = tracer?.NewSpan("��������");
+```
+
+ʹ�� `using` �ؼ���ȷ�� span �����������ʱ�Զ���ɣ���¼��ʱ�ʹ�����
+
+### ����ʾ��
+
+����������������ݵ����ʾ����
+
+```csharp
+private void Ss_Received(Object? sender, ReceivedEventArgs e)
+{
+ var ns = (this as INetSession).Host;
+ var tracer = ns?.Tracer;
+
+ // ������㣬��¼���ղ���
+ using var span = tracer?.NewSpan($"net:{ns?.Name}:Receive", e.Message);
+ try
+ {
+ OnReceive(e);
+ }
+ catch (Exception ex)
+ {
+ // ��Ǵ���¼�쳣��Ϣ
+ span?.SetError(ex, e.Message ?? e.Packet);
+ throw;
+ }
+}
+```
+
+���ʾ����ʾ�ˣ�
+- **�������**��ʹ�ö�̬���ɵ�����
+- **���ݱ�ǩ**���ڶ������� `e.Message` ��Ϊ���ݱ�ǩ
+- **�쳣����**��ͨ�� `SetError` ����쳣���
+- **�Զ���¼**��`using` ����Զ���¼��ʱ
+
+ͨ�������㣬���ǿ��ԣ�
+- ͳ�ƽ������ݰ��Ĵ���
+- ��¼ÿ�ν��յĺ�ʱ
+- ͳ���쳣��������
+- �鿴�������ݺͱ�ǩ
+
+---
+
+## ���Ľӿ�
+
+### ITracer �ӿ�
+
+���ܸ������������� APM �淶�ĺ��Ľӿڡ�
+
+```csharp
+public interface ITracer
+{
+ #region ����
+ /// <summary>�������ڡ���λ�룬Ĭ��15��</summary>
+ Int32 Period { get; set; }
+
+ /// <summary>������������������������ڣ����ֻ��¼ָ�������������¼���Ĭ��1</summary>
+ Int32 MaxSamples { get; set; }
+
+ /// <summary>����쳣�����������������ڣ����ֻ��¼ָ���������쳣�¼���Ĭ��10</summary>
+ Int32 MaxErrors { get; set; }
+
+ /// <summary>��ʱʱ�䡣������ʱ��ʱǿ�Ʋ�������λ���룬Ĭ��5000</summary>
+ Int32 Timeout { get; set; }
+
+ /// <summary>����ǩ���ȡ������ó���ʱ���ضϣ�Ĭ��1024�ַ�</summary>
+ Int32 MaxTagLength { get; set; }
+
+ /// <summary>��http/rpc����ע��TraceId�IJ�������Ϊ�ձ�ʾ��ע�룬Ĭ��W3C����traceparent</summary>
+ String? AttachParameter { get; set; }
+ #endregion
+
+ /// <summary>����Span������</summary>
+ /// <param name="name">�������ƣ����ڱ�ʶ��ͬ���������</param>
+ ISpanBuilder BuildSpan(String name);
+
+ /// <summary>��ʼһ��Span</summary>
+ /// <param name="name">�������ƣ����ڱ�ʶ��ͬ���������</param>
+ ISpan NewSpan(String name);
+
+ /// <summary>��ʼһ��Span��ָ�����ݱ�ǩ</summary>
+ /// <param name="name">�������ƣ����ڱ�ʶ��ͬ���������</param>
+ /// <param name="tag">���ݱ�ǩ����¼�ؼ�������Ϣ</param>
+ ISpan NewSpan(String name, Object? tag);
+
+ /// <summary>�ض�����Span���������ݣ����ü���</summary>
+ ISpanBuilder[] TakeAll();
+}
+```
+
+#### �ؼ�����˵��
+
+| ���� | Ĭ��ֵ | ˵�� |
+|-----|-------|------|
+| `Period` | 15�� | �������ڣ������ϱ����ݵ�ʱ���� |
+| `MaxSamples` | 1 | ÿ�������ڼ�¼�����������������ڻ��Ƶ���������ϵ |
+| `MaxErrors` | 10 | ÿ�������ڼ�¼���쳣������������������� |
+| `Timeout` | 5000ms | ��ʱ��ֵ��������ʱ��IJ����ᱻǿ�Ʋ��� |
+| `MaxTagLength` | 1024 | ��ǩ��ȣ������ᱻ�ض� |
+| `AttachParameter` | "traceparent" | HTTP/RPC ������ע�� TraceId �IJ���������ѭ W3C �� |
+
+��Щ����ͨ�����dz�������Ķ�̬�·������������ֶ����á�
+
+#### �����
+
+- **`NewSpan(String name)`**: ��õķ���������һ�������
+- **`NewSpan(String name, Object? tag)`**: ������㲢�������ݱ�ǩ
+- **`BuildSpan(String name)`**: ��ȡ�� SpanBuilder�����ڸ�����
+
+### ISpan �ӿ�
+
+���ܸ���Ƭ�Σ�����һ����������ʵ����
+
+```csharp
+public interface ISpan : IDisposable
+{
+ /// <summary>Ψһ��ʶ�����߳������ġ�Http��Rpc���ݣ���Ϊ�ڲ�Ƭ�εĸ���</summary>
+ String Id { get; set; }
+
+ /// <summary>����������ڱ�ʶ��ͬ���͵IJ���</summary>
+ String Name { get; set; }
+
+ /// <summary>����Ƭ�α�ʶ�����ڹ���������</summary>
+ String? ParentId { get; set; }
+
+ /// <summary>���ٱ�ʶ�������ڹ������Ƭ�Σ�����������ϵ�����߳������ġ�Http��Rpc����</summary>
+ String TraceId { get; set; }
+
+ /// <summary>��ʼʱ�䡣Unix����ʱ���</summary>
+ Int64 StartTime { get; set; }
+
+ /// <summary>����ʱ�䡣Unix����ʱ���</summary>
+ Int64 EndTime { get; set; }
+
+ /// <summary>�û���ֵ����¼�����ͱ�������ÿ�����ݿ�����������dz�ƽ̨����ͳ��</summary>
+ Int64 Value { get; set; }
+
+ /// <summary>���ݱ�ǩ����¼һЩ�������ݣ��������������Ӧ�����</summary>
+ String? Tag { get; set; }
+
+ /// <summary>������Ϣ����¼�쳣��Ϣ</summary>
+ String? Error { get; set; }
+
+ /// <summary>���ô�����Ϣ��ApiException����</summary>
+ void SetError(Exception ex, Object? tag = null);
+
+ /// <summary>�������ݱ�ǩ���ڲ�������Ƚض�</summary>
+ void SetTag(Object tag);
+
+ /// <summary>������㣬������ɼ�</summary>
+ void Abandon();
+}
+```
+
+#### �ؼ�����
+
+| ���� | ���� | ˵�� |
+|-----|------|------|
+| `Id` | String | Span Ψһ��ʶ����ѭ W3C �� |
+| `ParentId` | String? | ���� Span ID�����ڹ��������� |
+| `TraceId` | String | ��������ʶ��ͬһ�������е����� Span ������ͬ TraceId |
+| `StartTime` | Int64 | ��ʼʱ�䣨Unix ���룩 |
+| `EndTime` | Int64 | ����ʱ�䣨Unix ���룩 |
+| `Value` | Int64 | �û���ֵ���ɼ�¼ҵ��ָ�꣨�����ݿ������� |
+| `Tag` | String? | ���ݱ�ǩ����¼�����������Ӧ���ݵ� |
+| `Error` | String? | ������Ϣ |
+
+#### �����
+
+- **`SetError(Exception ex, Object? tag)`**: ����쳣��`ApiException` ���ͻᱻ�����
+- **`SetTag(Object tag)`**: �������ݱ�ǩ��֧�ֶ��������Զ����л�
+- **`Abandon()`**: ������ǰ��㣬�����ڹ�����Ч������404ɨ�裩
+
+---
+
+## ʹ�����ʵ��
+
+### 1. ע�� ITracer
+
+�� ASP.NET Core Ӧ���У�ͨ���dz���չע�룺
+
+```csharp
+using NewLife.Stardust.Extensions;
+
+var builder = WebApplication.CreateBuilder(args);
+
+// ע���dz������� ITracer ʵ��
+builder.Services.AddStardust();
+```
+
+�����[�dz��ֲ�ʽ����ƽ̨](https://newlifex.com/blood/stardust)
+
+### 2. ��ȡ ITracer ʵ��
+
+�ж��ַ�ʽ��ȡ `ITracer`��
+
+```csharp
+// ��ʽ1�����캯��ע�루�Ƽ���
+public class MyService
+{
+ private readonly ITracer _tracer;
+
+ public MyService(ITracer tracer)
+ {
+ _tracer = tracer;
+ }
+}
+
+// ��ʽ2������ע��
+public class MyService
+{
+ public ITracer? Tracer { get; set; }
+}
+
+// ��ʽ3��ʹ��ȫ�־�̬ʵ��
+var tracer = DefaultTracer.Instance;
+```
+
+### 3. �������
+
+#### �������
+
+```csharp
+using var span = _tracer?.NewSpan("MyOperation");
+// ҵ����
+```
+
+#### �����ݱ�ǩ�����
+
+```csharp
+var request = new { UserId = 123, Action = "Query" };
+using var span = _tracer?.NewSpan("UserQuery", request);
+// ҵ����
+```
+
+#### ���쳣���������
+
+```csharp
+using var span = _tracer?.NewSpan("DatabaseQuery");
+try
+{
+ // ִ�����ݿ��ѯ
+ var result = await ExecuteQueryAsync();
+}
+catch (Exception ex)
+{
+ span?.SetError(ex, "��ѯʧ��");
+ throw;
+}
+```
+
+#### ��¼ҵ��ָ��
+
+```csharp
+using var span = _tracer?.NewSpan("BatchProcess");
+var count = ProcessRecords();
+span.Value = count; // ��¼�����ļ�¼��
+```
+
+### 4. ��ʱ�������ʾ��
+
+```csharp
+public class DataRetentionService : IHostedService
+{
+ private readonly ITracer _tracer;
+ private readonly StarServerSetting _setting;
+ private TimerX? _timer;
+
+ public DataRetentionService(StarServerSetting setting, ITracer tracer)
+ {
+ _setting = setting;
+ _tracer = tracer;
+ }
+
+ public Task StartAsync(CancellationToken cancellationToken)
+ {
+ // ÿ600��ִ��һ�Σ�����ӳ�����
+ _timer = new TimerX(DoWork, null,
+ DateTime.Today.AddMinutes(Rand.Next(60)),
+ 600 * 1000)
+ {
+ Async = true
+ };
+
+ return Task.CompletedTask;
+ }
+
+ private void DoWork(Object? state)
+ {
+ var set = _setting;
+ if (set.DataRetention <= 0) return;
+
+ var time = DateTime.Now.AddDays(-set.DataRetention);
+ var time2 = DateTime.Now.AddDays(-set.DataRetention2);
+ var time3 = DateTime.Now.AddDays(-set.DataRetention3);
+
+ // ������㣬��¼��������
+ using var span = _tracer?.NewSpan("DataRetention", new { time, time2, time3 });
+ try
+ {
+ // ɾ��������
+ var rs = AppMinuteStat.DeleteBefore(time);
+ XTrace.WriteLine("ɾ��[{0}]֮ǰ��AppMinuteStat����{1:n0}", time, rs);
+
+ rs = TraceMinuteStat.DeleteBefore(time);
+ XTrace.WriteLine("ɾ��[{0}]֮ǰ��TraceMinuteStat����{1:n0}", time, rs);
+ }
+ catch (Exception ex)
+ {
+ span?.SetError(ex, null);
+ }
+ }
+
+ public Task StopAsync(CancellationToken cancellationToken)
+ {
+ _timer?.TryDispose();
+ return Task.CompletedTask;
+ }
+}
+```
+
+### 5. ����������
+
+�� Web Ӧ���У�������������ɨ��������ʹ�� `Abandon()` ������Щ��㣺
+
+```csharp
+public IActionResult ProcessRequest()
+{
+ using var span = _tracer?.NewSpan("WebRequest");
+
+ // ����Ч������404ɨ�裩
+ if (IsInvalidScan())
+ {
+ span?.Abandon(); // ������㣬������ͳ��
+ return NotFound();
+ }
+
+ // ��������
+ return Ok();
+}
+```
+
+---
+
+## �ֲ�ʽ��·��
+
+### �����
+
+ISpan �ṩ����չ������֧��ͨ�� HTTP/RPC ���ݸ��������ģ�
+
+```csharp
+// HTTP ����ע��
+var request = new HttpRequestMessage(HttpMethod.Get, url);
+span?.Attach(request); // ע�� traceparent ͷ
+await httpClient.SendAsync(request);
+
+// RPC ����ע��
+var args = new { UserId = 123 };
+span?.Attach(args); // ע����ٲ���
+await rpcClient.InvokeAsync("Method", args);
+```
+
+������յ�������Զ����� `traceparent` �������ָ����������ġ�
+
+### ����������
+
+ͬһ�� `TraceId` �µ����� Span ���Զ��γɵ�������
+
+```
+TraceId: ac1b1e8617342790000015eb0ea2a6
+���� DataRetention (��)
+ ���� SQL:AppMinuteStat.DeleteBefore (��)
+ ���� SQL:TraceMinuteStat.DeleteBefore (��)
+ ���� SQL:TraceHourStat.DeleteBefore (��)
+```
+
+���dz����ƽ̨���Բ鿴��
+- [����������ͼ](https://star.newlifex.com/trace?id=ac1b1e8617342790000015eb0ea2a6)
+- [��������־��ͼ](https://star.newlifex.com/trace?id=ac1b1e8617342790000015eb0ea2a6&layout=detail)
+
+---
+
+## ��������
+
+### �鿴ͳ������
+
+���dz����ƽ̨���Բ鿴���ͳ�ƣ�
+- �����ܴ���
+- �쳣����
+- ƽ����ʱ������ʱ����С��ʱ
+- QPS��ÿ����������
+
+ʾ����[DataRetention ���ͳ��](https://star.newlifex.com/Monitors/traceDayStat?appId=4&itemId=284)
+
+### ��������
+
+ITracer �������ܲ������ԣ�
+1. **��������**��ÿ����������ౣ�� `MaxSamples` ������������Ĭ��1����
+2. **�쳣����**��ÿ����������ౣ�� `MaxErrors` ���쳣������Ĭ��10����
+3. **��ʱ����**����ʱ���� `Timeout` �IJ���ǿ�Ʋ���
+4. **ȫ��·����**������ `TraceFlag` �ĵ�����ȫ������
+
+### ����ͳ�ƻ���
+
+ÿ���������Ӧһ�� `SpanBuilder`�������ۼ�ͳ�ƣ�
+- **Total**: �ܴ���
+- **Errors**: �쳣����
+- **Cost**: �ܺ�ʱ
+- **MaxCost**: ����ʱ
+- **MinCost**: ��С��ʱ
+
+ÿ���������ڽ�����`SpanBuilder` ���ݴ���ϱ���Ȼ�����ü�������
+
+---
+
+## ������
+
+### ��������淶
+
+����ʹ�÷ֲ����������ڷ���ͳ�ƣ�
+
+```csharp
+// �����
+tracer.NewSpan("net:{��}:Receive");
+tracer.NewSpan("net:tcp:Send");
+
+// ���ݿ��
+tracer.NewSpan("db:{����}:Select");
+tracer.NewSpan("db:User:Insert");
+
+// ҵ���
+tracer.NewSpan("biz:{�}:{����}");
+tracer.NewSpan("biz:Order:Create");
+
+// �ⲿ����
+tracer.NewSpan("http:{����}:{����}");
+tracer.NewSpan("http:PaymentApi:Pay");
+```
+
+### ��̬��������
+
+���Զ�̬��������������
+
+```csharp
+var tracer = DefaultTracer.Instance;
+tracer.Period = 30; // ��Ϊ30������
+tracer.MaxSamples = 5; // ��������������
+tracer.Timeout = 10000; // ��ʱ��ֵ��Ϊ10��
+tracer.MaxTagLength = 2048; // ��ǩ���ȸ�Ϊ2K
+```
+
+ͨ����Щ�������dz��������ͳһ�·���
+
+### �Զ��� ITracer ʵ��
+
+����ʵ���Լ��� `ITracer`��
+
+```csharp
+public class CustomTracer : ITracer
+{
+ public Int32 Period { get; set; } = 15;
+ public Int32 MaxSamples { get; set; } = 1;
+ public Int32 MaxErrors { get; set; } = 10;
+ // ... ʵ�ֽӿڷ���
+
+ public ISpan NewSpan(String name)
+ {
+ // �Զ�����㴴����
+ var span = new CustomSpan { Name = name };
+ span.Start();
+ return span;
+ }
+}
+
+// ע���Զ���ʵ��
+DefaultTracer.Instance = new CustomTracer();
+```
+
+---
+
+## ������
+
+### �����
+
+`DefaultTracer` �����˶���أ����� `ISpanBuilder` �� `ISpan` ʵ����
+
+```csharp
+public IPool<ISpanBuilder> BuilderPool { get; }
+public IPool<ISpan> SpanPool { get; }
+```
+
+Ƶ����������������Զ��黹����أ����� GC ѹ����
+
+### ��ǩ���ȿ���
+
+���ڴ��Ͷ�������Ʊ�ǩ���ݣ�
+
+```csharp
+// ���Ƽ�����¼���������
+span.SetTag(largeObject);
+
+// �Ƽ���ֻ��¼�ؼ���Ϣ
+span.SetTag(new { Id = obj.Id, Name = obj.Name });
+```
+
+### �������
+
+���ڷǹؼ�·�������������Դ�����㣺
+
+```csharp
+ISpan? span = null;
+if (_tracer != null && IsImportantOperation())
+{
+ span = _tracer.NewSpan("ImportantOp");
+}
+
+try
+{
+ // ҵ����
+}
+finally
+{
+ span?.Dispose();
+}
+```
+
+---
+
+## �쳣����
+
+### ApiException �����
+
+ҵ���쳣 `ApiException` ���ᱻ���Ϊ����
+
+```csharp
+catch (ApiException aex)
+{
+ span?.SetError(aex, request);
+ // ��¼Ϊ������㣬Tag�а���ҵ�������
+}
+catch (Exception ex)
+{
+ span?.SetError(ex, request);
+ // ��¼Ϊ�쳣��㣬Error�а����쳣��Ϣ
+}
+```
+
+### �쳣���
+
+ÿ���쳣���Զ������������쳣��㣬���ڰ��쳣����ͳ�ƣ�
+
+```csharp
+// ԭʼ���
+using var span = tracer.NewSpan("DatabaseQuery");
+
+try
+{
+ // �׳��쳣
+ throw new TimeoutException("��ѯ��ʱ");
+}
+catch (Exception ex)
+{
+ span.SetError(ex, query);
+ // �Զ����� "ex:TimeoutException" ���
+}
+```
+
+---
+
+## ��������
+
+### 1. ����������dz�ƽ̨��������
+
+������¼��㣺
+- ȷ����ע���dz���չ��`services.AddStardust()`
+- ����������ӵ��dz�������
+- ���Ӧ�����dz�ƽ̨�Ƿ���ע��
+- �鿴������־��ȷ�������������
+
+### 2. ��������̫�٣�
+
+��������������
+```csharp
+tracer.MaxSamples = 10; // ��������������
+tracer.MaxErrors = 50; // �����쳣������
+tracer.Timeout = 1000; // ���ͳ�ʱ��ֵ
+```
+
+### 3. ��ιر���㣿
+
+```csharp
+// ��ʽ1����ע�� ITracer
+// services.AddStardust(); // ע�͵�
+
+// ��ʽ2��ʹ�ÿ�ʵ��
+DefaultTracer.Instance = null;
+```
+
+### 4. ��β鿴����������ݣ�
+
+DefaultTracer ���������־��
+
+```
+Tracer[DataRetention] Total=10 Errors=0 Speed=0.02tps Cost=1500ms MaxCost=2000ms MinCost=1000ms
+```
+
+### 5. ���������� Span ������
+
+���ᡣ`ISpan` ʹ�� `AsyncLocal<ISpan>` ���������ģ�ÿ���첽���̶�����
+
+```csharp
+public static AsyncLocal<ISpan?> Current { get; }
+```
+
+---
+
+## �����
+
+- **�dz����ƽ̨**: https://newlifex.com/blood/stardust
+- **W3C Trace Context**: https://www.w3.org/TR/trace-context/
+- **Դ��ֿ�**: https://github.com/NewLifeX/X
+- **�����ĵ�**: https://newlifex.com/core/tracer
+
+---
+
+## ������־
+
+- **2024-12-16**: �����ĵ����������ʵ����ʾ������
+- **2024-08**: ֧�� .NET 9.0
+- **2023-11**: ���� `Abandon()` ����
+- **2023-06**: �Ż�����أ���������
+- **2022**: ��ʼ�汾����
diff --git a/Doc/Snowflake.md "b/Doc/\351\233\252\350\212\261\347\256\227\346\263\225Snowflake.md"
similarity index 100%
rename from Doc/Snowflake.md
rename to "Doc/\351\233\252\350\212\261\347\256\227\346\263\225Snowflake.md"
diff --git "a/Doc/\351\253\230\347\272\247\345\256\232\346\227\266\345\231\250TimerX.md" "b/Doc/\351\253\230\347\272\247\345\256\232\346\227\266\345\231\250TimerX.md"
new file mode 100644
index 0000000..b921b18
--- /dev/null
+++ "b/Doc/\351\253\230\347\272\247\345\256\232\346\227\266\345\231\250TimerX.md"
@@ -0,0 +1,761 @@
+# ����ʱ��TimerX
+
+## ����
+
+`NewLife.Threading.TimerX` ��һ������ǿ��Ķ�ʱ��ʵ�֣����ϵͳ `System.Threading.Timer` �����������ƣ�
+
+- **��������**���ص�ִ����Ϻ�ſ�ʼ��ʱ��һ��
+- **֧���첽�ص�**��ԭ��֧�� `async/await`
+- **����ʱ��ִ��**��֧�̶ֹ�ʱ��ִ�У���ÿ��2�㣩
+- **Cron ����ʽ**��֧�ָ��ӵĶ�ʱ����
+- **��·��**������ `ITracer` ���֧��
+- **��ȫ�ͷ�**�������ھ�̬�������ϣ����ⱻGC��ǰ����
+
+**�����ռ�**: `NewLife.Threading`
+**Դ��**: [NewLife.Core/Threading/TimerX.cs](https://github.com/NewLifeX/X/blob/master/NewLife.Core/Threading/TimerX.cs)
+
+---
+
+## ��������
+
+### �����÷���������ִ��
+
+```csharp
+using NewLife.Threading;
+
+// 1����״�ִ�У�Ȼ��ÿ5��ִ��һ��
+var timer = new TimerX(state =>
+{
+ Console.WriteLine($"ִ��ʱ�䣺{DateTime.Now}");
+}, null, 1000, 5000);
+
+// ʹ����ϼǵ��ͷ�
+timer.Dispose();
+```
+
+**����˵��**��
+- `state`���û����ݣ��ᴫ�ݸ��ص�����
+- `dueTime`���ӳ�ʱ�䣨���룩���״�ִ��ǰ�ȴ���ʱ��
+- `period`��������ڣ����룩����Ϊ0��-1��ʾִֻ��һ��
+
+### �첽�ص�
+
+```csharp
+// ֧�� async/await ���첽�ص�
+var timer = new TimerX(async state =>
+{
+ await Task.Delay(100); // ģ���첽����
+ Console.WriteLine("�첽�������");
+}, null, 1000, 5000);
+```
+
+**�Զ�����**��
+- ʹ�� `Func<Object, Task>` ʱ���Զ����� `IsAsyncTask = true` �� `Async = true`
+
+### ����ʱ��ִ��
+
+```csharp
+// ÿ���賿2��ִ��
+var start = DateTime.Today.AddHours(2);
+var timer = new TimerX(state =>
+{
+ Console.WriteLine("ִ��������������");
+}, null, start, 24 * 3600 * 1000); // ����24Сʱ
+```
+
+**�ص�**��
+- ��� `startTime` С�ڵ�ǰʱ�䣬���Զ��� `period` ֱ�����ڵ�ǰʱ��
+- �Զ����� `Absolutely = true`
+- ���� `SetNext` Ӱ�죬ʼ���ڹ̶�ʱ��ִ��
+
+### Cron ����ʽ
+
+```csharp
+// ÿ������������9��ִ��
+var timer = new TimerX(state =>
+{
+ Console.WriteLine("����������");
+}, null, "0 0 9 * * 1-5");
+
+// ֧�ֶ��Cron����ʽ���ֺŷָ�
+var timer2 = new TimerX(state =>
+{
+ Console.WriteLine("�������");
+}, null, "0 0 2 * * 1-5;0 0 3 * * 6"); // ������2�㣬����3��
+```
+
+**�Զ�����**��
+- ʹ�� Cron ����ʽʱ���Զ����� `Absolutely = true`
+- ��һ��ִ��ʱ���� Cron ����
+
+---
+
+## ��������
+
+### 1. �����������
+
+ϵͳ `Timer` �����⣺
+```csharp
+// System.Threading.Timer ������
+var timer = new Timer(_ =>
+{
+ Thread.Sleep(3000); // ���������ʱ3��
+ Console.WriteLine("ִ��");
+}, null, 0, 1000); // ÿ1�봥��
+
+// ���������ͬʱ�ж���ص���ִ�У���ɲ������⣡
+```
+
+TimerX �Ľ��������
+```csharp
+var timer = new TimerX(_ =>
+{
+ Thread.Sleep(3000); // ��ʱ3��
+ Console.WriteLine("ִ��");
+}, null, 0, 1000);
+
+// ִ�����̣�
+// 0�룺��ʼ��1��ִ��
+// 3�룺��1��ִ����ϣ��ȴ�1��
+// 4�룺��ʼ��2��ִ��
+// 7�룺��2��ִ����ϣ��ȴ�1��
+// 8�룺��ʼ��3��ִ��
+// ...
+```
+
+**ԭ��**���ص�ִ����Ϻ�ſ�ʼ������һ�ε��ӳ�ʱ�䣬ȷ��ͬһʱ��ֻ��һ���ص���ִ�С�
+
+### 2. ���� TickCount �ľ���ʱ
+
+TimerX ʹ�� `Runtime.TickCount64` ��Ϊ��ʱ������ϵͳʱ��ز���
+
+```csharp
+// ��ʹ�ֶ�����ϵͳʱ�䣬TimerX Ҳ����Ӱ��
+var timer = new TimerX(_ =>
+{
+ Console.WriteLine($"ִ�У�{DateTime.Now}");
+}, null, 0, 5000);
+```
+
+**����**��
+- ʹ�ÿ������������ϵͳʱ��
+- ��������ʱ��ʱ������Ӱ��
+- ÿ�� `SetNextTick` ��ˢ��ʱ������Զ�����Ư��
+
+### 3. ����ʱ���� Cron
+
+- **`Absolutely = true`**����ʾ����ʱ��ִ�У����� `SetNext` Ӱ��
+- **Cron ���캯��**���Զ����� `Absolutely = true`��ͨ�� `Cron.GetNext(now)` ������һ��ִ��ʱ��
+
+```csharp
+// ����ʱ�䶨ʱ��
+var timer = new TimerX(_ => { }, null, DateTime.Today.AddHours(2), 24 * 3600 * 1000);
+timer.Absolutely; // true
+
+// Cron ��ʱ��
+var timer2 = new TimerX(_ => { }, null, "0 0 2 * * *");
+timer2.Absolutely; // true
+timer2.Crons; // Cron����
+```
+
+---
+
+## ���캯�����
+
+### 1. ��ͨ���ڶ�ʱ����ͬ����
+
+```csharp
+public TimerX(TimerCallback callback, Object? state, Int32 dueTime, Int32 period, String? scheduler = null)
+```
+
+**����**��
+- `callback`: �ص�ί�� `void Callback(Object state)`
+- `state`: �û�����
+- `dueTime`: �ӳ�ʱ�䣨���룩���״�ִ��ǰ�ȴ�
+- `period`: ������ڣ����룩��0��-1��ʾִֻ��һ��
+- `scheduler`: ���������ƣ�Ĭ��ʹ�� `TimerScheduler.Default`
+
+**ʾ��**��
+```csharp
+var timer = new TimerX(_ =>
+{
+ Console.WriteLine("ִ��");
+}, null, 1000, 5000);
+```
+
+### 2. �첽���ڶ�ʱ��
+
+```csharp
+public TimerX(Func<Object, Task> callback, Object? state, Int32 dueTime, Int32 period, String? scheduler = null)
+```
+
+**����**��
+- `callback`: �첽�ص�ί�� `async Task Callback(Object state)`
+- ��������ͬ��
+
+**�Զ�����**��
+- `IsAsyncTask = true`
+- `Async = true`
+
+**ʾ��**��
+```csharp
+var timer = new TimerX(async _ =>
+{
+ await DoWorkAsync();
+}, null, 1000, 5000);
+```
+
+### 3. ����ʱ�䶨ʱ����ͬ����
+
+```csharp
+public TimerX(TimerCallback callback, Object? state, DateTime startTime, Int32 period, String? scheduler = null)
+```
+
+**����**��
+- `startTime`: ���Կ�ʼʱ�䣬ָ��ʱ��ִ��
+- `period`: ������ڣ����룩���������0
+
+**�Զ�����**��
+- `Absolutely = true`
+- ��� `startTime` С�ڵ�ǰʱ�䣬�Զ��� `period` ����
+
+**ʾ��**��
+```csharp
+// ÿ���賿2��ִ��
+var start = DateTime.Today.AddHours(2);
+var timer = new TimerX(_ =>
+{
+ Console.WriteLine("�賿����");
+}, null, start, 24 * 3600 * 1000);
+```
+
+### 4. ����ʱ�䶨ʱ�����첽��
+
+```csharp
+public TimerX(Func<Object, Task> callback, Object? state, DateTime startTime, Int32 period, String? scheduler = null)
+```
+
+**�Զ�����**��
+- `IsAsyncTask = true`
+- `Async = true`
+- `Absolutely = true`
+
+### 5. Cron ��ʱ����ͬ����
+
+```csharp
+public TimerX(TimerCallback callback, Object? state, String cronExpression, String? scheduler = null)
+```
+
+**����**��
+- `cronExpression`: Cron ����ʽ��֧�ַֺŷָ��������ʽ
+
+**�Զ�����**��
+- `Absolutely = true`
+- ��������ʽ�����浽 `_crons` ����
+
+**ʾ��**��
+```csharp
+// ÿ������������9��
+var timer = new TimerX(_ =>
+{
+ Console.WriteLine("����������");
+}, null, "0 0 9 * * 1-5");
+
+// ���ʱ���
+var timer2 = new TimerX(_ =>
+{
+ Console.WriteLine("�������");
+}, null, "0 0 2 * * 1-5;0 0 3 * * 6");
+```
+
+### 6. Cron ��ʱ�����첽��
+
+```csharp
+public TimerX(Func<Object, Task> callback, Object? state, String cronExpression, String? scheduler = null)
+```
+
+**�Զ�����**��
+- `IsAsyncTask = true`
+- `Async = true`
+- `Absolutely = true`
+
+---
+
+## ��������
+
+| ���� | ���� | ˵�� |
+|-----|------|------|
+| `Id` | Int32 | ��ʱ��Ψһ��ʶ���Զ����� |
+| `Period` | Int32 | ������ڣ����룩��0��-1��ʾִֻ��һ�� |
+| `Async` | Boolean | �Ƿ��첽ִ�У�Ĭ�� false |
+| `Absolutely` | Boolean | �Ƿ���Ծ�ȷʱ��ִ�У�Ĭ�� false |
+| `Calling` | Boolean | �ص��Ƿ�����ִ�У�ֻ���� |
+| `Timers` | Int32 | �ۼƵ��ô�����ֻ���� |
+| `Cost` | Int32 | ƽ����ʱ�����룬ֻ���� |
+| `NextTime` | DateTime | ��һ�ε���ʱ�䣨ֻ���� |
+| `NextTick` | Int64 | ��һ��ִ��ʱ����������ֻ���� |
+| `Crons` | Cron[] | Cron ����ʽ���ϣ�ֻ���� |
+| `Tracer` | ITracer | ��·���� |
+| `TracerName` | String | ��·�����ƣ�Ĭ�� `timer:{������}` |
+| `State` | Object | �û����ݣ������ô洢 |
+| `Scheduler` | TimerScheduler | ���������� |
+
+---
+
+## �����
+
+### SetNext - ������һ��ִ��ʱ��
+
+```csharp
+/// <summary>������һ������ʱ��</summary>
+/// <param name="ms">�ӳٺ�������С�ڵ���0��ʾ���ϵ���</param>
+public void SetNext(Int32 ms)
+```
+
+**ʾ��**��
+```csharp
+var timer = new TimerX(_ =>
+{
+ Console.WriteLine("ִ��");
+
+ // ��̬������һ��ִ��ʱ��
+ if (someCondition)
+ timer.SetNext(10000); // 10���ִ��
+ else
+ timer.SetNext(1000); // 1���ִ��
+}, null, 1000, 5000);
+```
+
+**ע��**��
+- ���� `Absolutely = true` �Ķ�ʱ��������ʱ�䡢Cron����`SetNext` ��Ч
+- ���ú�ỽ�ѵ������������
+
+### Change - ���ļ�ʱ������
+
+```csharp
+/// <summary>���ļ�ʱ��������ʱ��ͷ�������֮���ʱ����</summary>
+/// <param name="dueTime">�ӳ�ʱ��</param>
+/// <param name="period">�������</param>
+/// <returns>�Ƿ�ɹ�����</returns>
+public Boolean Change(TimeSpan dueTime, TimeSpan period)
+```
+
+**ʾ��**��
+```csharp
+var timer = new TimerX(_ =>
+{
+ Console.WriteLine("ִ��");
+}, null, 1000, 5000);
+
+// ��Ϊ2����״�ִ�У�Ȼ��ÿ10��һ��
+timer.Change(TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(10));
+```
+
+**����**��
+- ���� `Absolutely = true` �Ķ�ʱ�������� false����ʧ��
+- ���� Cron ��ʱ�������� false����ʧ��
+- `period` Ϊ������ Infinite ʱ����ʱ���ᱻ����
+
+### Dispose - ���ٶ�ʱ��
+
+```csharp
+/// <summary>���ٶ�ʱ��</summary>
+public void Dispose()
+```
+
+**ʾ��**��
+```csharp
+var timer = new TimerX(_ =>
+{
+ Console.WriteLine("ִ��");
+}, null, 1000, 5000);
+
+// ʹ������ͷ�
+timer.Dispose();
+```
+
+**��Ҫ��**��
+- TimerX �����ھ�̬������ `TimerScheduler` ��
+- **�����ֶ����� `Dispose()`** ���ܴӵ������Ƴ�
+- ���������ڴ�й©�Ͷ�ʱ������ִ��
+
+---
+
+## ��̬����
+
+### Delay - �ӳ�ִ��
+
+```csharp
+/// <summary>�ӳ�ִ��һ��ί��</summary>
+/// <param name="callback">�ص�ί��</param>
+/// <param name="ms">�ӳٺ�����</param>
+/// <returns>��ʱ��ʵ��</returns>
+public static TimerX Delay(TimerCallback callback, Int32 ms)
+```
+
+**ʾ��**��
+```csharp
+// 10���ִ��һ�Σ�Ȼ������
+var timer = TimerX.Delay(_ =>
+{
+ Console.WriteLine("�ӳ�����ִ��");
+}, 10000);
+
+// ע�⣺ί�п��ܻ�ûִ�У�timer����ͱ�GC������
+// ���鱣��timer����
+```
+
+**ע��**��
+- �Զ����� `Async = true`
+- ��ִ��һ�Σ�Period=0��
+- **����**����������� `timer` ���ã����ܱ� GC ���յ���δִ��
+
+### Now - ����ĵ�ǰʱ��
+
+```csharp
+/// <summary>��ǰʱ�䡣��ʱ��ȡϵͳʱ�䣬����Ƶ����ȡ�������ƿ��</summary>
+public static DateTime Now { get; }
+```
+
+**ʾ��**��
+```csharp
+var now = TimerX.Now; // �������� DateTime.Now
+Console.WriteLine(now);
+```
+
+**ԭ��**��
+- ÿ500�������һ��ϵͳʱ��
+- ����Ƶ������ `DateTime.Now` �������ƿ��
+- �����ڶ�ʱ�侫��Ҫ�ߵij�������500ms��
+
+---
+
+## ������ TimerScheduler
+
+TimerX ���� `TimerScheduler` ����ͳһ���ȡ�
+
+### Ĭ�ϵ�����
+
+```csharp
+var timer = new TimerX(_ => { }, null, 1000, 5000);
+timer.Scheduler; // TimerScheduler.Default
+```
+
+### �Զ��������
+
+```csharp
+// ����ר��������
+var timer = new TimerX(_ =>
+{
+ Console.WriteLine("ִ��");
+}, null, 1000, 5000, "MyScheduler");
+
+timer.Scheduler.Name; // "MyScheduler"
+```
+
+**����**��
+- ��Ҫ�����ĵ����̳߳�
+- ���벻ͬҵ��Ķ�ʱ��
+- ���Ʋ�ͬ�����������ȼ�
+
+---
+
+## ��·��
+
+TimerX ������·��֧�֣��Զ�Ϊÿ��ִ�д��� Span��
+
+### ��������
+
+```csharp
+using NewLife.Log;
+
+var timer = new TimerX(_ =>
+{
+ Console.WriteLine("ִ��");
+}, null, 1000, 5000)
+{
+ Tracer = DefaultTracer.Instance, // ��������
+ TracerName = "MyTask" // �Զ����������
+};
+```
+
+### ������
+
+ÿ�ζ�ʱ���������ᴴ��һ�� Span��
+- **����**��Ĭ��Ϊ `timer:{������}`����ͨ�� `TracerName` �Զ���
+- **��ǩ**����¼��ʱ��ID�����ڵ���Ϣ
+- **��ʱ**����¼ÿ�λص�ִ�е�ʱ��
+
+**�鿴ͳ��**��
+```
+Tracer[timer:DoWork] Total=100 Errors=0 Speed=0.02tps Cost=150ms MaxCost=200ms MinCost=100ms
+```
+
+�����[��·��ITracer](tracer-��·��ITracer.md)
+
+---
+
+## ʹ�ó���
+
+### 1. ������������
+
+```csharp
+// ÿ���賿3��������������
+var timer = new TimerX(state =>
+{
+ var days = (Int32)state!;
+ var before = DateTime.Now.AddDays(-days);
+
+ var count = Database.Delete("WHERE CreateTime < @time", new { time = before });
+ Console.WriteLine($"������ {count} ����������");
+}, 30, DateTime.Today.AddHours(3), 24 * 3600 * 1000);
+```
+
+### 2. �������
+
+```csharp
+var timer = new TimerX(_ =>
+{
+ foreach (var client in clients)
+ {
+ if (client.LastActive.AddMinutes(5) < DateTime.Now)
+ {
+ Console.WriteLine($"�ͻ��� {client.Id} ��ʱ���Ͽ�����");
+ client.Disconnect();
+ }
+ }
+}, null, 0, 60000); // ÿ���Ӽ��һ��
+```
+
+### 3. ��������ͬ��
+
+```csharp
+var timer = new TimerX(async _ =>
+{
+ var data = await FetchDataFromApiAsync();
+ await SaveToDatabase(data);
+ Console.WriteLine("����ͬ�����");
+}, null, 0, 300000); // ÿ5����ͬ��һ��
+```
+
+### 4. �����ն�ʱ����
+
+```csharp
+// ÿ������������9�����ɱ���
+var timer = new TimerX(_ =>
+{
+ var report = GenerateReport(DateTime.Today.AddDays(-1));
+ SendEmail(report);
+ Console.WriteLine("�����ѷ���");
+}, null, "0 0 9 * * 1-5");
+```
+
+### 5. ���ڽ������
+
+```csharp
+var timer = new TimerX(_ =>
+{
+ var healthy = CheckSystemHealth();
+ if (!healthy)
+ {
+ SendAlert("ϵͳ�쳣");
+ }
+}, null, 0, 30000); // ÿ30����һ��
+```
+
+---
+
+## ���ʵ��
+
+### 1. �첽�ص�����
+
+���ں�ʱ������ʹ���첽�ص�����������
+
+```csharp
+// �Ƽ�
+var timer = new TimerX(async _ =>
+{
+ await DoHeavyWorkAsync();
+}, null, 0, 5000);
+
+// ���Ƽ�
+var timer2 = new TimerX(_ =>
+{
+ DoHeavyWork(); // �����߳�
+}, null, 0, 5000);
+```
+
+### 2. �����ͷ���Դ
+
+```csharp
+public class MyService : IDisposable
+{
+ private readonly TimerX _timer;
+
+ public MyService()
+ {
+ _timer = new TimerX(_ => DoWork(), null, 0, 5000);
+ }
+
+ public void Dispose()
+ {
+ _timer?.Dispose(); // �ͷŶ�ʱ��
+ }
+}
+```
+
+### 3. ʹ�� Current ����
+
+�ڻص��п��Է��ʵ�ǰ��ʱ����
+
+```csharp
+var timer = new TimerX(_ =>
+{
+ var current = TimerX.Current;
+ Console.WriteLine($"��ʱ��[{current.Id}]��{current.Timers}��ִ��");
+
+ // ��̬��������
+ if (current.Timers > 10)
+ current.Period = 10000;
+}, null, 0, 5000);
+```
+
+### 4. ������
+
+```csharp
+var timer = new TimerX(_ =>
+{
+ try
+ {
+ DoWork();
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"��ʱ�����쳣��{ex.Message}");
+ // ��¼��־����Ҫ�׳��쳣
+ }
+}, null, 0, 5000);
+```
+
+### 5. Cron ���ӳ���
+
+```csharp
+// ����������9�㣬��������10��
+var crons = "0 0 9 * * 1-5;0 0 10 * * 6";
+var timer = new TimerX(_ =>
+{
+ Console.WriteLine("ִ������");
+}, null, crons);
+```
+
+---
+
+## ע������
+
+### 1. ���������ͷ�
+
+```csharp
+var timer = new TimerX(_ => { }, null, 0, 5000);
+// ... ʹ�� ...
+timer.Dispose(); // ������ã������ڴ�й©
+```
+
+### 2. Delay ����������
+
+```csharp
+// ����timer���ܱ�GC����
+TimerX.Delay(_ => Console.WriteLine("ִ��"), 10000);
+
+// ��ȷ����������
+var timer = TimerX.Delay(_ => Console.WriteLine("ִ��"), 10000);
+// ... ����timer���������� ...
+```
+
+### 3. ����ʱ�䲻����
+
+```csharp
+var timer = new TimerX(_ => { }, null, DateTime.Today.AddHours(2), 86400000);
+timer.SetNext(1000); // ��Ч
+timer.Change(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(5)); // ���� false
+```
+
+### 4. State ��������
+
+```csharp
+var obj = new MyObject();
+var timer = new TimerX(_ =>
+{
+ var state = _.State as MyObject; // ����Ϊ null
+}, obj, 0, 5000);
+
+// ��� obj �� GC ���գ�State ���Ϊ null
+```
+
+### 5. ����Ϊ0ִֻ��һ��
+
+```csharp
+var timer = new TimerX(_ =>
+{
+ Console.WriteLine("ִֻ��һ��");
+}, null, 1000, 0); // Period=0��ִֻ��һ��
+```
+
+---
+
+## ��������
+
+### 1. ��ʱ����ִ�У�
+
+��飺
+- �Ƿ� GC ���գ��������ã�
+- �Ƿ��� Dispose
+- Period �Ƿ�Ϊ����
+- Cron ����ʽ�Ƿ���ȷ
+
+### 2. ��ʱ��ִ���˶�Σ�
+
+TimerX �Dz�������ģ��������������⡣������֣�����Ƿ��˶����ʱ��ʵ����
+
+### 3. ���ֹͣ��ʱ����
+
+```csharp
+timer.Dispose(); // ���ٲ��Ƴ�
+```
+
+### 4. �����ͣ�ͻָ���
+
+```csharp
+// ��ͣ������Ϊִֻ��һ�Σ�
+timer.Change(Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan);
+
+// �ָ�
+timer.Change(TimeSpan.Zero, TimeSpan.FromSeconds(5));
+```
+
+### 5. Cron �;���ʱ�������
+
+| ���� | Cron | ����ʱ�� |
+|-----|------|---------|
+| ����ʽ | ֧�ָ��ӹ��� | �̶�ʱ��+���� |
+| ����� | �ߣ��뼶�����ڵȣ� | �ͣ��̶����ڣ� |
+| ���� | �Եͣ�������� | �� |
+| ���ó��� | ���Ӷ�ʱ | ������ |
+
+---
+
+## �����
+
+- **Cron �ĵ�**: [cron-Cron����ʽ.md](cron-Cron����ʽ.md)
+- **��·��**: [tracer-��·��ITracer.md](tracer-��·��ITracer.md)
+- **�����ĵ�**: https://newlifex.com/core/timerx
+- **Դ��**: https://github.com/NewLifeX/X/blob/master/NewLife.Core/Threading/TimerX.cs
+
+---
+
+## ������־
+
+- **2025-01**: �����ĵ���������ϸʾ�������ʵ��
+- **2024**: ֧�� .NET 9.0���Ż�����
+- **2023**: ���� Cron �����ʽ֧��
+- **2022**: �����첽�ص�֧��
+- **2020**: ��ʼ�汾������ TickCount �ľ���ʱ