Explorar o código

1.新增任意进制转换操作
2.新增纳秒级性能计数器

懒得勤快 %!s(int64=7) %!d(string=hai) anos
pai
achega
7332095708
Modificáronse 61 ficheiros con 1313 adicións e 264 borrados
  1. 13 2
      Masuit.Tools.Core/DateTimeExt/ChineseCalendar.cs
  2. 26 1
      Masuit.Tools.Core/DateTimeExt/DateInfoStruct.cs
  3. 25 0
      Masuit.Tools.Core/DateTimeExt/WeekHolidayStruct.cs
  4. 17 0
      Masuit.Tools.Core/Linq/LinqExtension.cs
  5. 20 1
      Masuit.Tools.Core/Linq/ParameterReplacer.cs
  6. 22 1
      Masuit.Tools.Core/Logging/LogLevel.cs
  7. 2 2
      Masuit.Tools.Core/Masuit.Tools.Core.csproj
  8. 3 0
      Masuit.Tools.Core/Net/FtpClient.cs
  9. 74 2
      Masuit.Tools.Core/Net/MultiThreadDownloader.cs
  10. 86 6
      Masuit.Tools.Core/Net/PartialDownloader.cs
  11. 2 0
      Masuit.Tools.Core/NoSQL/RedisHelper.cs
  12. 88 0
      Masuit.Tools.Core/Strings/NumberFormater.cs
  13. 18 1
      Masuit.Tools.Core/Strings/Template.cs
  14. 15 0
      Masuit.Tools.Core/Systems/ConcurrentLimitedQueue.cs
  15. 15 2
      Masuit.Tools.Core/Systems/Disposable.cs
  16. 86 0
      Masuit.Tools.Core/Systems/HiPerfTimer.cs
  17. 11 0
      Masuit.Tools.Core/Systems/LimitedQueue.cs
  18. 20 2
      Masuit.Tools.Core/Systems/Lock.cs
  19. 28 3
      Masuit.Tools.Core/Systems/RedisLock.cs
  20. 5 0
      Masuit.Tools.Core/Validator/ComplexPassword.cs
  21. 8 0
      Masuit.Tools.Core/Validator/IsEmailAttribute.cs
  22. 5 0
      Masuit.Tools.Core/Validator/IsIPAddressAttribute.cs
  23. 5 0
      Masuit.Tools.Core/Validator/IsPhoneAttribute.cs
  24. 15 0
      Masuit.Tools.Core/Validator/MaxValueAttribute.cs
  25. 15 0
      Masuit.Tools.Core/Validator/MinValueAttribute.cs
  26. 12 12
      Masuit.Tools.NoSQL.MongoDBClient.Core/MongoDbClient.cs
  27. 2 2
      Masuit.Tools.NoSQL.MongoDBClient/Masuit.Tools.NoSQL.MongoDBClient.csproj
  28. 17 9
      Masuit.Tools.NoSQL.MongoDBClient/MongoDbClient.cs
  29. 1 1
      Masuit.Tools.NoSQL.MongoDBClient/packages.config
  30. 1 0
      Masuit.Tools.UnitTest/Masuit.Tools.UnitTest.csproj
  31. 34 0
      Masuit.Tools.UnitTest/NumberFormaterTest.cs
  32. 1 0
      Masuit.Tools.UnitTest/TemplateTest.cs
  33. 14 3
      Masuit.Tools/DateTimeExt/ChineseCalendar.cs
  34. 26 1
      Masuit.Tools/DateTimeExt/DateInfoStruct.cs
  35. 25 0
      Masuit.Tools/DateTimeExt/WeekHolidayStruct.cs
  36. 6 6
      Masuit.Tools/Linq/LinqExtension.cs
  37. 13 5
      Masuit.Tools/Linq/ParameterReplacer.cs
  38. 22 1
      Masuit.Tools/Logging/LogLevel.cs
  39. 6 4
      Masuit.Tools/Masuit.Tools.csproj
  40. 3 0
      Masuit.Tools/Net/FtpClient.cs
  41. 74 2
      Masuit.Tools/Net/MultiThreadDownloader.cs
  42. 85 5
      Masuit.Tools/Net/PartialDownloader.cs
  43. 2 2
      Masuit.Tools/Properties/AssemblyInfo.cs
  44. 103 0
      Masuit.Tools/Strings/NumberFormater.cs
  45. 18 1
      Masuit.Tools/Strings/Template.cs
  46. 15 0
      Masuit.Tools/Systems/ConcurrentLimitedQueue.cs
  47. 15 2
      Masuit.Tools/Systems/Disposable.cs
  48. 4 4
      Masuit.Tools/Systems/EnumExt.cs
  49. 72 0
      Masuit.Tools/Systems/HiPerfTimer.cs
  50. 11 0
      Masuit.Tools/Systems/LimitedQueue.cs
  51. 20 2
      Masuit.Tools/Systems/Lock.cs
  52. 28 3
      Masuit.Tools/Systems/RedisLock.cs
  53. 2 2
      Masuit.Tools/Validator/ComplexPassword.cs
  54. 3 3
      Masuit.Tools/Validator/IsEmailAttribute.cs
  55. 4 4
      Masuit.Tools/Validator/IsIPAddressAttribute.cs
  56. 2 2
      Masuit.Tools/Validator/IsPhoneAttribute.cs
  57. 13 1
      Masuit.Tools/Validator/MaxValueAttribute.cs
  58. 16 1
      Masuit.Tools/Validator/MinValueAttribute.cs
  59. 16 160
      Test/Program.cs
  60. 2 2
      Test/Test.csproj
  61. 1 1
      Test/packages.config

+ 13 - 2
Masuit.Tools.Core/DateTimeExt/ChineseCalendar.cs

@@ -966,6 +966,7 @@ namespace Masuit.Tools.DateTimeExt
                         tempStr = sh.HolidayName;
                         break;
                     }
+
                     if (CustomHolidays.Keys.Any(d => d.Date == _date))
                     {
                         tempStr = CustomHolidays[_date];
@@ -977,8 +978,14 @@ namespace Masuit.Tools.DateTimeExt
             }
         }
 
+        /// <summary>
+        /// 今天是否是假期
+        /// </summary>
         public bool IsHoliday => !IsWorkDay;
 
+        /// <summary>
+        /// 今天是否是工作日
+        /// </summary>
         public bool IsWorkDay
         {
             get
@@ -1241,7 +1248,9 @@ namespace Masuit.Tools.DateTimeExt
             }
         }
 
-        //当前日期前一个最近节气
+        /// <summary>
+        /// 当前日期前一个最近节气
+        /// </summary>
         public string ChineseTwentyFourPrevDay
         {
             get
@@ -1264,7 +1273,9 @@ namespace Masuit.Tools.DateTimeExt
             }
         }
 
-        //当前日期后一个最近节气
+        /// <summary>
+        /// 当前日期后一个最近节气
+        /// </summary>
         public string ChineseTwentyFourNextDay
         {
             get

+ 26 - 1
Masuit.Tools.Core/DateTimeExt/DateInfoStruct.cs

@@ -1,12 +1,37 @@
 namespace Masuit.Tools.DateTimeExt
 {
+    /// <summary>
+    /// 日期信息
+    /// </summary>
     public struct DateInfoStruct
     {
+        /// <summary>
+        /// 月
+        /// </summary>
         public readonly int Month;
+
+        /// <summary>
+        /// 日
+        /// </summary>
         public readonly int Day;
-        public readonly int Recess; //假期长度
+
+        /// <summary>
+        /// 假期长度
+        /// </summary>
+        public readonly int Recess;
+
+        /// <summary>
+        /// 节假日名
+        /// </summary>
         public readonly string HolidayName;
 
+        /// <summary>
+        /// 日期信息
+        /// </summary>
+        /// <param name="month"></param>
+        /// <param name="day"></param>
+        /// <param name="recess"></param>
+        /// <param name="name"></param>
         public DateInfoStruct(int month, int day, int recess, string name)
         {
             Month = month;

+ 25 - 0
Masuit.Tools.Core/DateTimeExt/WeekHolidayStruct.cs

@@ -1,12 +1,37 @@
 namespace Masuit.Tools.DateTimeExt
 {
+    /// <summary>
+    /// 节假日信息
+    /// </summary>
     public struct WeekHolidayStruct
     {
+        /// <summary>
+        /// 月
+        /// </summary>
         public readonly int Month;
+
+        /// <summary>
+        /// 这个月第几周
+        /// </summary>
         public readonly int WeekAtMonth;
+
+        /// <summary>
+        /// 周末日
+        /// </summary>
         public readonly int WeekDay;
+
+        /// <summary>
+        /// 假日名
+        /// </summary>
         public readonly string HolidayName;
 
+        /// <summary>
+        /// 节假日信息
+        /// </summary>
+        /// <param name="month"></param>
+        /// <param name="weekAtMonth"></param>
+        /// <param name="weekDay"></param>
+        /// <param name="name"></param>
         public WeekHolidayStruct(int month, int weekAtMonth, int weekDay, string name)
         {
             Month = month;

+ 17 - 0
Masuit.Tools.Core/Linq/LinqExtension.cs

@@ -3,8 +3,18 @@ using System.Linq.Expressions;
 
 namespace Masuit.Tools.Core.Linq
 {
+    /// <summary>
+    /// linq扩展类
+    /// </summary>
     public static class LinqExtension
     {
+        /// <summary>
+        /// 与连接
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="left">左条件</param>
+        /// <param name="right">右条件</param>
+        /// <returns></returns>
         public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> left, Expression<Func<T, bool>> right)
         {
             var dateExpr = Expression.Parameter(typeof(T));
@@ -15,6 +25,13 @@ namespace Masuit.Tools.Core.Linq
             return Expression.Lambda<Func<T, bool>>(body, dateExpr);
         }
 
+        /// <summary>
+        /// 或连接
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="left">左条件</param>
+        /// <param name="right">右条件</param>
+        /// <returns></returns>
         public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> left, Expression<Func<T, bool>> right)
         {
             var dateExpr = Expression.Parameter(typeof(T));

+ 20 - 1
Masuit.Tools.Core/Linq/ParameterReplacer.cs

@@ -2,20 +2,39 @@
 
 namespace Masuit.Tools.Core.Linq
 {
+    /// <summary>
+    /// linq参数替换器
+    /// </summary>
     public class ParameterReplacer : ExpressionVisitor
     {
+        /// <summary>
+        /// linq参数替换器
+        /// </summary>
+        /// <param name="paramExpr"></param>
         public ParameterReplacer(ParameterExpression paramExpr)
         {
             this.ParameterExpression = paramExpr;
         }
 
+        /// <summary>
+        /// 参数表达式
+        /// </summary>
         public ParameterExpression ParameterExpression { get; private set; }
 
+        /// <summary>
+        /// 表达式替换
+        /// </summary>
+        /// <param name="expr"></param>
+        /// <returns></returns>
         public Expression Replace(Expression expr)
         {
             return this.Visit(expr);
         }
-
+        /// <summary>
+        /// 表达式参数访问
+        /// </summary>
+        /// <param name="p"></param>
+        /// <returns></returns>
         protected override Expression VisitParameter(ParameterExpression p)
         {
             return this.ParameterExpression;

+ 22 - 1
Masuit.Tools.Core/Logging/LogLevel.cs

@@ -1,7 +1,28 @@
 namespace Masuit.Tools.Logging
 {
+    /// <summary>
+    /// 日志级别
+    /// </summary>
     public enum LogLevel
     {
-        Info, Debug, Error, Fatal
+        /// <summary>
+        /// 信息级别
+        /// </summary>
+        Info,
+
+        /// <summary>
+        /// debug级别
+        /// </summary>
+        Debug,
+
+        /// <summary>
+        /// 错误级别
+        /// </summary>
+        Error,
+
+        /// <summary>
+        /// 致命级别
+        /// </summary>
+        Fatal
     }
 }

+ 2 - 2
Masuit.Tools.Core/Masuit.Tools.Core.csproj

@@ -2,7 +2,7 @@
 
   <PropertyGroup>
     <TargetFramework>netcoreapp2.1</TargetFramework>
-    <Version>2.1.4.3</Version>
+    <Version>2.1.5</Version>
     <Authors>懒得勤快</Authors>
     <Company>masuit.com</Company>
     <Description>包含一些常用的操作类,大都是静态类,加密解密,反射操作,硬件信息,字符串扩展方法,日期时间扩展操作,大文件拷贝,图像裁剪,html处理,验证码、NoSql等常用封装。
@@ -88,7 +88,7 @@ string s = html.HtmlSantinizerStandard();//清理后:&lt;div&gt;&lt;span&gt;&l
     <PackageReference Include="AngleSharp" Version="0.9.11" />
     <PackageReference Include="HtmlSanitizer" Version="4.0.199" />
     <PackageReference Include="Microsoft.AspNetCore.All" Version="2.1.5" />
-    <PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
+    <PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
     <PackageReference Include="SharpZipLib" Version="1.0.0" />
     <PackageReference Include="System.Drawing.Common" Version="4.5.1" />
   </ItemGroup>

+ 3 - 0
Masuit.Tools.Core/Net/FtpClient.cs

@@ -29,6 +29,9 @@ namespace Masuit.Tools.Net
         /// </summary>
         public static string Password { get; set; }
 
+        /// <summary>
+        /// ftp地址
+        /// </summary>
         public static string FtpUri = "ftp://" + FtpServer + "/";
 
         #endregion

+ 74 - 2
Masuit.Tools.Core/Net/MultiThreadDownloader.cs

@@ -39,6 +39,13 @@ namespace Masuit.Tools.Net
 
         #region 下载管理器
 
+        /// <summary>
+        /// 多线程下载管理器
+        /// </summary>
+        /// <param name="sourceUrl"></param>
+        /// <param name="tempDir"></param>
+        /// <param name="savePath"></param>
+        /// <param name="numOfParts"></param>
         public MultiThreadDownloader(string sourceUrl, string tempDir, string savePath, int numOfParts)
         {
             _url = sourceUrl;
@@ -49,11 +56,22 @@ namespace Masuit.Tools.Net
             FilePath = savePath;
         }
 
+        /// <summary>
+        /// 多线程下载管理器
+        /// </summary>
+        /// <param name="sourceUrl"></param>
+        /// <param name="savePath"></param>
+        /// <param name="numOfParts"></param>
         public MultiThreadDownloader(string sourceUrl, string savePath, int numOfParts) : this(sourceUrl, null, savePath, numOfParts)
         {
             TempFileDirectory = Environment.GetEnvironmentVariable("temp");
         }
 
+        /// <summary>
+        /// 多线程下载管理器
+        /// </summary>
+        /// <param name="sourceUrl"></param>
+        /// <param name="numOfParts"></param>
         public MultiThreadDownloader(string sourceUrl, int numOfParts) : this(sourceUrl, null, numOfParts)
         {
         }
@@ -184,6 +202,11 @@ namespace Masuit.Tools.Net
             return new PartialDownloader(_url, TempFileDirectory, Guid.NewGuid().ToString(), start, end, true);
         }
 
+        /// <summary>
+        /// 暂停或继续
+        /// </summary>
+        /// <param name="list"></param>
+        /// <param name="wait"></param>
         public static void WaitOrResumeAll(List<PartialDownloader> list, bool wait)
         {
             foreach (PartialDownloader item in list)
@@ -195,7 +218,10 @@ namespace Masuit.Tools.Net
             }
         }
 
-
+        /// <summary>
+        /// 冒泡排序
+        /// </summary>
+        /// <param name="list"></param>
         private static void BubbleSort(List<PartialDownloader> list)
         {
             bool switched = true;
@@ -215,17 +241,32 @@ namespace Masuit.Tools.Net
             }
         }
 
-        //Sorts the downloader by From property to merge the parts
+        /// <summary>
+        /// Sorts the downloader by From property to merge the parts
+        /// </summary>
+        /// <param name="list"></param>
+        /// <returns></returns>
         public static List<PartialDownloader> SortPDsByFrom(List<PartialDownloader> list)
         {
             return list.OrderBy(x => x.From).ToList();
         }
 
+        /// <summary>
+        /// 按剩余时间排序
+        /// </summary>
+        /// <param name="list"></param>
         public static void OrderByRemaining(List<PartialDownloader> list)
         {
             BubbleSort(list);
         }
 
+        /// <summary>
+        /// 获取内容长度
+        /// </summary>
+        /// <param name="url"></param>
+        /// <param name="rangeAllowed"></param>
+        /// <param name="redirectedUrl"></param>
+        /// <returns></returns>
         public static long GetContentLength(string url, ref bool rangeAllowed, ref string redirectedUrl)
         {
             HttpWebRequest req = WebRequest.Create(url) as HttpWebRequest;
@@ -311,31 +352,62 @@ namespace Masuit.Tools.Net
 
         #region 公共属性
 
+        /// <summary>
+        /// RangeAllowed
+        /// </summary>
         public bool RangeAllowed
         {
             get => _rangeAllowed;
             set => _rangeAllowed = value;
         }
 
+        /// <summary>
+        /// 临时文件夹
+        /// </summary>
         public string TempFileDirectory { get; set; }
 
+        /// <summary>
+        /// url地址
+        /// </summary>
         public string Url
         {
             get => _url;
             set => _url = value;
         }
 
+        /// <summary>
+        /// 第几部分
+        /// </summary>
         public int NumberOfParts { get; set; }
 
+        /// <summary>
+        /// 已接收字节数
+        /// </summary>
         public long TotalBytesReceived => PartialDownloaderList.Where(t => t != null).Sum(t => t.TotalBytesRead);
 
+        /// <summary>
+        /// 总进度
+        /// </summary>
         public int TotalProgress { get; private set; }
 
+        /// <summary>
+        /// 文件大小
+        /// </summary>
         public long Size { get; private set; }
 
+        /// <summary>
+        /// 下载速度
+        /// </summary>
         public int TotalSpeedInBytes => PartialDownloaderList.Sum(t => t.SpeedInBytes);
+
+        /// <summary>
+        /// 下载块
+        /// </summary>
         public List<PartialDownloader> PartialDownloaderList { get; }
 
+        /// <summary>
+        /// 文件路径
+        /// </summary>
         public string FilePath { get; set; }
 
         #endregion

+ 86 - 6
Masuit.Tools.Core/Net/PartialDownloader.cs

@@ -8,13 +8,28 @@ using System.Threading;
 
 namespace Masuit.Tools.Net
 {
+    /// <summary>
+    /// 部分下载器
+    /// </summary>
     public class PartialDownloader
     {
         #region Variables
 
+        /// <summary>
+        /// 这部分完成事件
+        /// </summary>
         public event EventHandler DownloadPartCompleted;
+
+        /// <summary>
+        /// 部分下载进度改变事件
+        /// </summary>
         public event EventHandler DownloadPartProgressChanged;
+
+        /// <summary>
+        /// 部分下载停止事件
+        /// </summary>
         public event EventHandler DownloadPartStopped;
+
         HttpWebRequest _req;
         HttpWebResponse _resp;
         Stream _tempStream;
@@ -29,6 +44,15 @@ namespace Masuit.Tools.Net
 
         #region PartialDownloader
 
+        /// <summary>
+        /// 部分块下载
+        /// </summary>
+        /// <param name="url"></param>
+        /// <param name="dir"></param>
+        /// <param name="fileGuid"></param>
+        /// <param name="from"></param>
+        /// <param name="to"></param>
+        /// <param name="rangeAllowed"></param>
         public PartialDownloader(string url, string dir, string fileGuid, int from, int to, bool rangeAllowed)
         {
             _from = from;
@@ -58,7 +82,7 @@ namespace Masuit.Tools.Net
                 _req.ServicePoint.ConnectionLimit += 1;
                 _req.ServicePoint.Expect100Continue = true;
                 _req.ProtocolVersion = HttpVersion.Version10;
-                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Ssl3;
+                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.SystemDefault;
                 ServicePointManager.Expect100Continue = true;
                 if (_rangeAllowed)
                     _req.AddRange(_from, _to);
@@ -89,12 +113,12 @@ namespace Masuit.Tools.Net
                         }
 
                         if (_totalBytesRead + bytesRead > _contentLength)
-                            bytesRead = (int) (_contentLength - _totalBytesRead);
+                            bytesRead = (int)(_contentLength - _totalBytesRead);
                         _file.Write(buffer, 0, bytesRead);
                         _totalBytesRead += bytesRead;
-                        _lastSpeeds[_counter] = (int) (_totalBytesRead / Math.Ceiling(_stp.Elapsed.TotalSeconds));
+                        _lastSpeeds[_counter] = (int)(_totalBytesRead / Math.Ceiling(_stp.Elapsed.TotalSeconds));
                         _counter = (_counter >= 9) ? 0 : _counter + 1;
-                        int tempProgress = (int) (_totalBytesRead * 100 / _contentLength);
+                        int tempProgress = (int)(_totalBytesRead * 100 / _contentLength);
                         if (_progress != tempProgress)
                         {
                             _progress = tempProgress;
@@ -143,6 +167,9 @@ namespace Masuit.Tools.Net
 
         #region Public Methods
 
+        /// <summary>
+        /// 启动下载
+        /// </summary>
         public void Start()
         {
             _stop = false;
@@ -150,17 +177,25 @@ namespace Masuit.Tools.Net
             procThread.Start();
         }
 
+        /// <summary>
+        /// 下载停止
+        /// </summary>
         public void Stop()
         {
             _stop = true;
         }
 
-        //Wait is used when repartitiate a partition securely in this project
+        /// <summary>
+        /// 暂停等待下载
+        /// </summary>
         public void Wait()
         {
             _wait = true;
         }
 
+        /// <summary>
+        /// 稍后唤醒
+        /// </summary>
         public void ResumeAfterWait()
         {
             _wait = false;
@@ -185,24 +220,54 @@ namespace Masuit.Tools.Net
 
         #region Properties
 
+        /// <summary>
+        /// 下载已停止
+        /// </summary>
         public bool Stopped => _stop;
 
+        /// <summary>
+        /// 下载已完成
+        /// </summary>
         public bool Completed => _completed;
 
+        /// <summary>
+        /// 下载进度
+        /// </summary>
         public int Progress => _progress;
 
+        /// <summary>
+        /// 下载目录
+        /// </summary>
         public string Directory => _directory;
 
+        /// <summary>
+        /// 文件名
+        /// </summary>
         public string FileName => _fileGuid;
 
+        /// <summary>
+        /// 已读字节数
+        /// </summary>
         public long TotalBytesRead => _totalBytesRead;
 
+        /// <summary>
+        /// 内容长度
+        /// </summary>
         public long ContentLength => _contentLength;
 
+        /// <summary>
+        /// RangeAllowed
+        /// </summary>
         public bool RangeAllowed => _rangeAllowed;
 
+        /// <summary>
+        /// url
+        /// </summary>
         public string Url => _url;
 
+        /// <summary>
+        /// to
+        /// </summary>
         public int To
         {
             get => _to;
@@ -213,14 +278,29 @@ namespace Masuit.Tools.Net
             }
         }
 
+        /// <summary>
+        /// from
+        /// </summary>
         public int From => _from;
 
+        /// <summary>
+        /// 当前位置
+        /// </summary>
         public int CurrentPosition => _from + _totalBytesRead - 1;
 
-        public int RemainingBytes => (int) (_contentLength - _totalBytesRead);
+        /// <summary>
+        /// 剩余字节数
+        /// </summary>
+        public int RemainingBytes => (int)(_contentLength - _totalBytesRead);
 
+        /// <summary>
+        /// 完整路径
+        /// </summary>
         public string FullPath => Path.Combine(_directory, _fileGuid);
 
+        /// <summary>
+        /// 下载速度
+        /// </summary>
         public int SpeedInBytes
         {
             get

+ 2 - 0
Masuit.Tools.Core/NoSQL/RedisHelper.cs

@@ -102,6 +102,7 @@ namespace Masuit.Tools.NoSQL
         /// </summary>
         /// <param name="readWriteHosts">Redis服务器连接字符串,格式:127.0.0.1:6379,allowadmin=true,abortConnect=false</param>
         /// <param name="dbNum">数据库的编号</param>
+        /// <param name="_"></param>
         private RedisHelper(string readWriteHosts, int dbNum, int _)
         {
             DbNum = dbNum;
@@ -567,6 +568,7 @@ namespace Masuit.Tools.NoSQL
         /// <param name="key">键</param>
         /// <param name="dataKey">对象的字段</param>
         /// <param name="t">对象实例</param>
+        /// <param name="expire">过期时间</param>
         /// <returns>是否存储成功</returns>
         public async Task<bool> SetHashAsync<T>(string key, string dataKey, T t, TimeSpan expire)
         {

+ 88 - 0
Masuit.Tools.Core/Strings/NumberFormater.cs

@@ -0,0 +1,88 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Masuit.Tools.Strings
+{
+    /// <summary>
+    /// 数制格式化器
+    /// </summary>
+    public class NumberFormater
+    {
+        /// <summary>
+        /// 数制表示字符集
+        /// </summary>
+        private string Characters { get; set; }
+
+        /// <summary>
+        /// 进制长度
+        /// </summary>
+        public int Length => Characters?.Length ?? 0;
+
+        /// <summary>
+        /// 数制格式化器
+        /// </summary>
+        public NumberFormater()
+        {
+            Characters = "0123456789";
+        }
+
+        /// <summary>
+        /// 数制格式化器
+        /// </summary>
+        /// <param name="characters">进制转换</param>
+        public NumberFormater(string characters)
+        {
+            Characters = characters;
+        }
+
+        /// <summary>
+        /// 数字转换为指定的进制形式字符串
+        /// </summary>
+        /// <param name="number"></param>
+        /// <returns></returns>
+        public string ToString(long number)
+        {
+            List<string> result = new List<string>();
+            long t = number;
+
+            while (t > 0)
+            {
+                var mod = t % Length;
+                t = Math.Abs(t / Length);
+                var character = Characters[Convert.ToInt32(mod)].ToString();
+                result.Insert(0, character);
+            }
+
+            return string.Join("", result.ToArray());
+        }
+
+        /// <summary>
+        /// 指定字符串转换为指定进制的数字形式
+        /// </summary>
+        /// <param name="str"></param>
+        /// <returns></returns>
+        public long FromString(string str)
+        {
+            long result = 0;
+            int j = 0;
+            foreach (var ch in new string(str.ToCharArray().Reverse().ToArray()))
+            {
+                if (Characters.Contains(ch))
+                {
+                    result += Characters.IndexOf(ch) * (long)Math.Pow(Length, j);
+                    j++;
+                }
+            }
+
+            return result;
+        }
+
+        /// <summary>Returns a string that represents the current object.</summary>
+        /// <returns>A string that represents the current object.</returns>
+        public override string ToString()
+        {
+            return Length + "模式";
+        }
+    }
+}

+ 18 - 1
Masuit.Tools.Core/Strings/Template.cs

@@ -3,21 +3,38 @@ using System.Text.RegularExpressions;
 
 namespace Masuit.Tools.Strings
 {
+    /// <summary>
+    /// 模版引擎
+    /// </summary>
     public class Template
     {
         private string Content { get; set; }
 
+        /// <summary>
+        /// 模版引擎
+        /// </summary>
+        /// <param name="content"></param>
         public Template(string content)
         {
             Content = content;
         }
 
+        /// <summary>
+        /// 设置变量
+        /// </summary>
+        /// <param name="key"></param>
+        /// <param name="value"></param>
+        /// <returns></returns>
         public Template Set(string key, string value)
         {
             Content = Content.Replace("{{" + key + "}}", value);
             return this;
         }
 
+        /// <summary>
+        /// 渲染模板
+        /// </summary>
+        /// <returns></returns>
         public string Render()
         {
             var mc = Regex.Matches(Content, @"\{\{.+?\}\}");
@@ -25,8 +42,8 @@ namespace Masuit.Tools.Strings
             {
                 throw new ArgumentException($"模版变量{m.Value}未被使用");
             }
+
             return Content;
         }
-
     }
 }

+ 15 - 0
Masuit.Tools.Core/Systems/ConcurrentLimitedQueue.cs

@@ -10,18 +10,33 @@ namespace Masuit.Tools.Systems
     /// <typeparam name="T"></typeparam>
     public class ConcurrentLimitedQueue<T> : ConcurrentQueue<T>
     {
+        /// <summary>
+        /// 长度
+        /// </summary>
         public int Limit { get; set; }
 
+        /// <summary>
+        /// 定长队列
+        /// </summary>
+        /// <param name="limit"></param>
         public ConcurrentLimitedQueue(int limit)
         {
             Limit = limit;
         }
 
+        /// <summary>
+        /// 定长队列
+        /// </summary>
+        /// <param name="list"></param>
         public ConcurrentLimitedQueue(IEnumerable<T> list) : base(list)
         {
             Limit = list.Count();
         }
 
+        /// <summary>
+        /// 入队
+        /// </summary>
+        /// <param name="item"></param>
         public new void Enqueue(T item)
         {
             if (Count >= Limit)

+ 15 - 2
Masuit.Tools.Core/Systems/Disposable.cs

@@ -2,26 +2,39 @@
 
 namespace Masuit.Tools.Systems
 {
+    /// <summary>
+    /// Disposable
+    /// </summary>
     public abstract class Disposable : IDisposable
     {
         private bool isDisposed;
 
+        /// <summary>
+        /// 终结器
+        /// </summary>
         ~Disposable()
         {
             Dispose(false);
         }
 
+        /// <summary>
+        /// 
+        /// </summary>
         public void Dispose()
         {
             if (isDisposed)
             {
                 return;
             }
+
             Dispose(true);
             isDisposed = true;
             GC.SuppressFinalize(this);
         }
-
+        /// <summary>
+        /// 释放
+        /// </summary>
+        /// <param name="disposing"></param>
         public abstract void Dispose(bool disposing);
     }
-}
+}

+ 86 - 0
Masuit.Tools.Core/Systems/HiPerfTimer.cs

@@ -0,0 +1,86 @@
+using System;
+using System.ComponentModel;
+using System.Runtime.InteropServices;
+using System.Threading;
+
+namespace Masuit.Tools.Systems
+{
+    /// <summary>
+    /// 纳秒级计时器
+    /// </summary>
+    public class HiPerfTimer
+    {
+        [DllImport("Kernel32.dll")]
+        private static extern bool QueryPerformanceCounter(out long lpPerformanceCount);
+
+        [DllImport("Kernel32.dll")]
+        private static extern bool QueryPerformanceFrequency(out long lpFrequency);
+
+        private long _startTime;
+        private long _stopTime;
+        private readonly long _freq;
+
+        /// <summary>
+        /// 纳秒计数器
+        /// </summary>
+        public HiPerfTimer()
+        {
+            _startTime = 0;
+            _stopTime = 0;
+
+            if (QueryPerformanceFrequency(out _freq) == false)
+            {
+                // 不支持高性能计数器 
+                throw new Win32Exception();
+            }
+        }
+
+        /// <summary>
+        /// 开始计时器
+        /// </summary>
+        public void Start()
+        {
+            // 来让等待线程工作 
+            Thread.Sleep(0);
+            QueryPerformanceCounter(out _startTime);
+        }
+
+        /// <summary>
+        /// 启动一个新的计时器
+        /// </summary>
+        /// <returns></returns>
+        public static HiPerfTimer StartNew()
+        {
+            HiPerfTimer timer = new HiPerfTimer();
+            timer.Start();
+            return timer;
+        }
+
+        /// <summary>
+        /// 停止计时器
+        /// </summary>
+        public void Stop()
+        {
+            QueryPerformanceCounter(out _stopTime);
+        }
+
+        /// <summary>
+        /// 时器经过时间(单位:秒)
+        /// </summary>
+        public double Duration => (_stopTime - _startTime) / (double)_freq;
+
+        /// <summary>
+        /// 执行一个方法并测试执行时间
+        /// </summary>
+        /// <param name="action"></param>
+        /// <returns></returns>
+        public static double Execute(Action action)
+        {
+            var timer = new HiPerfTimer();
+            timer.Start();
+            action();
+            timer.Stop();
+            return timer.Duration;
+        }
+    }
+}

+ 11 - 0
Masuit.Tools.Core/Systems/LimitedQueue.cs

@@ -8,13 +8,24 @@ namespace Masuit.Tools.Systems
     /// <typeparam name="T"></typeparam>
     public class LimitedQueue<T> : Queue<T>
     {
+        /// <summary>
+        /// 队列长度
+        /// </summary>
         public int Limit { get; set; }
 
+        /// <summary>
+        /// 定长队列
+        /// </summary>
+        /// <param name="limit"></param>
         public LimitedQueue(int limit) : base(limit)
         {
             Limit = limit;
         }
 
+        /// <summary>
+        /// 入队
+        /// </summary>
+        /// <param name="item"></param>
         public new void Enqueue(T item)
         {
             if (Count >= Limit)

+ 20 - 2
Masuit.Tools.Core/Systems/Lock.cs

@@ -1,10 +1,19 @@
-using System;
-using StackExchange.Redis;
+using StackExchange.Redis;
+using System;
 
 namespace Masuit.Tools.Systems
 {
+    /// <summary>
+    /// 分布式锁
+    /// </summary>
     public class Lock
     {
+        /// <summary>
+        /// 分布式锁
+        /// </summary>
+        /// <param name="resource"></param>
+        /// <param name="val"></param>
+        /// <param name="validity"></param>
         public Lock(RedisKey resource, RedisValue val, TimeSpan validity)
         {
             Resource = resource;
@@ -12,10 +21,19 @@ namespace Masuit.Tools.Systems
             Validity = validity;
         }
 
+        /// <summary>
+        /// 
+        /// </summary>
         public RedisKey Resource { get; }
 
+        /// <summary>
+        /// 
+        /// </summary>
         public RedisValue Value { get; }
 
+        /// <summary>
+        /// 
+        /// </summary>
         public TimeSpan Validity { get; }
     }
 }

+ 28 - 3
Masuit.Tools.Core/Systems/RedisLock.cs

@@ -1,18 +1,24 @@
-using System;
+using StackExchange.Redis;
+using System;
 using System.Collections.Concurrent;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Timers;
-using StackExchange.Redis;
 
 namespace Masuit.Tools.Systems
 {
+    /// <summary>
+    /// Redis分布式锁
+    /// </summary>
     public class RedisLock : IDisposable
     {
         #region Property
 
         private bool _isDisposed;
 
+        /// <summary>
+        /// 终结器
+        /// </summary>
         ~RedisLock()
         {
             Dispose(false);
@@ -245,13 +251,21 @@ namespace Masuit.Tools.Systems
             return task;
         }
 
+        /// <summary>
+        /// 创建唯一锁id
+        /// </summary>
+        /// <returns></returns>
         protected static string CreateUniqueLockId()
         {
             return string.Concat(Guid.NewGuid().ToString(), Thread.CurrentThread.ManagedThreadId);
         }
 
+        /// <summary>
+        /// 设置超时
+        /// </summary>
+        /// <param name="doWork"></param>
+        /// <param name="time"></param>
         protected void SetTimeOut(ElapsedEventHandler doWork, int time)
-
         {
             System.Timers.Timer timer = new System.Timers.Timer();
             timer.Interval = time;
@@ -260,6 +274,13 @@ namespace Masuit.Tools.Systems
             timer.Start();
         }
 
+        /// <summary>
+        /// 任务超时
+        /// </summary>
+        /// <param name="action"></param>
+        /// <param name="lockObj"></param>
+        /// <param name="time"></param>
+        /// <returns></returns>
         protected CancellationTokenSource TaskTimeOut(Func<Lock, bool> action, Lock lockObj, int time)
         {
             var timeoutCancellationTokenSource = new CancellationTokenSource();
@@ -310,6 +331,10 @@ namespace Masuit.Tools.Systems
             GC.SuppressFinalize(this);
         }
 
+        /// <summary>
+        /// 释放锁
+        /// </summary>
+        /// <param name="disposing"></param>
         public virtual void Dispose(bool disposing)
         {
             if (_isDisposed)

+ 5 - 0
Masuit.Tools.Core/Validator/ComplexPassword.cs

@@ -8,6 +8,11 @@ namespace Masuit.Tools.Core.Validator
     /// </summary>
     public class ComplexPassword : ValidationAttribute
     {
+        /// <summary>
+        /// 校验密码强度
+        /// </summary>
+        /// <param name="value"></param>
+        /// <returns></returns>
         public override bool IsValid(object value)
         {
             string pwd = value as string;

+ 8 - 0
Masuit.Tools.Core/Validator/IsEmailAttribute.cs

@@ -2,8 +2,16 @@
 
 namespace Masuit.Tools.Core.Validator
 {
+    /// <summary>
+    /// 邮箱校验
+    /// </summary>
     public class IsEmailAttribute : ValidationAttribute
     {
+        /// <summary>
+        /// 邮箱校验
+        /// </summary>
+        /// <param name="value"></param>
+        /// <returns></returns>
         public override bool IsValid(object value)
         {
             if (value == null)

+ 5 - 0
Masuit.Tools.Core/Validator/IsIPAddressAttribute.cs

@@ -7,6 +7,11 @@ namespace Masuit.Tools.Core.Validator
     /// </summary>
     public class IsIPAddressAttribute : ValidationAttribute
     {
+        /// <summary>
+        /// 验证IPv4地址是否合法
+        /// </summary>
+        /// <param name="value"></param>
+        /// <returns></returns>
         public override bool IsValid(object value)
         {
             if (value is null)

+ 5 - 0
Masuit.Tools.Core/Validator/IsPhoneAttribute.cs

@@ -7,6 +7,11 @@ namespace Masuit.Tools.Core.Validator
     /// </summary>
     public class IsPhoneAttribute : ValidationAttribute
     {
+        /// <summary>
+        /// 验证手机号码是否合法
+        /// </summary>
+        /// <param name="value"></param>
+        /// <returns></returns>
         public override bool IsValid(object value)
         {
             if (value is null)

+ 15 - 0
Masuit.Tools.Core/Validator/MaxValueAttribute.cs

@@ -3,19 +3,34 @@ using System.ComponentModel.DataAnnotations;
 
 namespace Masuit.Tools.Core.Validator
 {
+    /// <summary>
+    /// 最大值校验
+    /// </summary>
     public class MaxValueAttribute : ValidationAttribute
     {
         private double MaxValue { get; }
+
+        /// <summary>
+        /// 最大值
+        /// </summary>
+        /// <param name="value"></param>
         public MaxValueAttribute(double value)
         {
             MaxValue = value;
         }
+
+        /// <summary>
+        /// 最大值校验
+        /// </summary>
+        /// <param name="value"></param>
+        /// <returns></returns>
         public override bool IsValid(object value)
         {
             if (value is null)
             {
                 return true;
             }
+
             var input = Convert.ToDouble(value);
             return input <= MaxValue;
         }

+ 15 - 0
Masuit.Tools.Core/Validator/MinValueAttribute.cs

@@ -3,19 +3,34 @@ using System.ComponentModel.DataAnnotations;
 
 namespace Masuit.Tools.Core.Validator
 {
+    /// <summary>
+    /// 最小值校验
+    /// </summary>
     public class MinValueAttribute : ValidationAttribute
     {
         private double MinValue { get; set; }
+
+        /// <summary>
+        /// 最小值
+        /// </summary>
+        /// <param name="value"></param>
         public MinValueAttribute(double value)
         {
             MinValue = value;
         }
+
+        /// <summary>
+        /// 最小值校验
+        /// </summary>
+        /// <param name="value"></param>
+        /// <returns></returns>
         public override bool IsValid(object value)
         {
             if (value is null)
             {
                 return true;
             }
+
             var input = Convert.ToDouble(value);
             return input > MinValue;
         }

+ 12 - 12
Masuit.Tools.NoSQL.MongoDBClient.Core/MongoDbClient.cs

@@ -1,12 +1,12 @@
-using System;
+using Masuit.Tools.NoSQL.MongoDBClient.Core;
+using MongoDB.Bson;
+using MongoDB.Driver;
+using System;
 using System.Collections.Concurrent;
 using System.Collections.Generic;
 using System.Linq;
 using System.Linq.Expressions;
 using System.Threading.Tasks;
-using Masuit.Tools.NoSQL.MongoDBClient.Core;
-using MongoDB.Bson;
-using MongoDB.Driver;
 
 namespace Masuit.Tools.NoSQL.MongoDBClient
 {
@@ -1029,7 +1029,7 @@ namespace Masuit.Tools.NoSQL.MongoDBClient
             {
                 if (!list.Current.Any(doc => doc["name"].AsString.StartsWith(index)))
                 {
-                    return mgr.CreateOne(asc ? Builders<BsonDocument>.IndexKeys.Ascending(doc => doc[index]) : Builders<BsonDocument>.IndexKeys.Descending(doc => doc[index]));
+                    return mgr.CreateOne(new CreateIndexModel<BsonDocument>(asc ? Builders<BsonDocument>.IndexKeys.Ascending(doc => doc[index]) : Builders<BsonDocument>.IndexKeys.Descending(doc => doc[index])));
                 }
             }
             return string.Empty;
@@ -1050,7 +1050,7 @@ namespace Masuit.Tools.NoSQL.MongoDBClient
             {
                 if (!list.Current.Any(doc => doc["name"].AsString.StartsWith(index)))
                 {
-                    return await mgr.CreateOneAsync(asc ? Builders<BsonDocument>.IndexKeys.Ascending(doc => doc[index]) : Builders<BsonDocument>.IndexKeys.Descending(doc => doc[index]));
+                    return await mgr.CreateOneAsync(new CreateIndexModel<BsonDocument>(asc ? Builders<BsonDocument>.IndexKeys.Ascending(doc => doc[index]) : Builders<BsonDocument>.IndexKeys.Descending(doc => doc[index])));
                 }
             }
             return string.Empty;
@@ -1066,7 +1066,7 @@ namespace Masuit.Tools.NoSQL.MongoDBClient
         public string UpdateIndex(string collection, string index, bool asc = true)
         {
             IMongoIndexManager<BsonDocument> mgr = Database.GetCollection<BsonDocument>(collection).Indexes;
-            return mgr.CreateOne(asc ? Builders<BsonDocument>.IndexKeys.Ascending(doc => doc[index]) : Builders<BsonDocument>.IndexKeys.Descending(doc => doc[index]));
+            return mgr.CreateOne(new CreateIndexModel<BsonDocument>(asc ? Builders<BsonDocument>.IndexKeys.Ascending(doc => doc[index]) : Builders<BsonDocument>.IndexKeys.Descending(doc => doc[index])));
         }
 
         /// <summary>
@@ -1079,7 +1079,7 @@ namespace Masuit.Tools.NoSQL.MongoDBClient
         public async Task<string> UpdateIndexAsync(string collection, string index, bool asc = true)
         {
             IMongoIndexManager<BsonDocument> mgr = Database.GetCollection<BsonDocument>(collection).Indexes;
-            return await mgr.CreateOneAsync(asc ? Builders<BsonDocument>.IndexKeys.Ascending(doc => doc[index]) : Builders<BsonDocument>.IndexKeys.Descending(doc => doc[index]));
+            return await mgr.CreateOneAsync(new CreateIndexModel<BsonDocument>(asc ? Builders<BsonDocument>.IndexKeys.Ascending(doc => doc[index]) : Builders<BsonDocument>.IndexKeys.Descending(doc => doc[index])));
         }
 
         /// <summary>
@@ -1120,7 +1120,7 @@ namespace Masuit.Tools.NoSQL.MongoDBClient
             {
                 if (!list.Current.Any(doc => doc["name"].AsString.StartsWith(index)))
                 {
-                    return mgr.CreateOne(asc ? Builders<T>.IndexKeys.Ascending(key) : Builders<T>.IndexKeys.Descending(key));
+                    return mgr.CreateOne(new CreateIndexModel<T>(asc ? Builders<T>.IndexKeys.Ascending(key) : Builders<T>.IndexKeys.Descending(key)));
                 }
             }
             return String.Empty;
@@ -1142,7 +1142,7 @@ namespace Masuit.Tools.NoSQL.MongoDBClient
             {
                 if (!list.Current.Any(doc => doc["name"].AsString.StartsWith(index)))
                 {
-                    return await mgr.CreateOneAsync(asc ? Builders<T>.IndexKeys.Ascending(key) : Builders<T>.IndexKeys.Descending(key));
+                    return await mgr.CreateOneAsync(new CreateIndexModel<T>(asc ? Builders<T>.IndexKeys.Ascending(key) : Builders<T>.IndexKeys.Descending(key)));
                 }
             }
             return String.Empty;
@@ -1158,7 +1158,7 @@ namespace Masuit.Tools.NoSQL.MongoDBClient
         public string UpdateIndex<T>(string collection, Expression<Func<T, object>> key, bool asc = true)
         {
             IMongoIndexManager<T> mgr = Database.GetCollection<T>(collection).Indexes;
-            return mgr.CreateOne(asc ? Builders<T>.IndexKeys.Ascending(key) : Builders<T>.IndexKeys.Descending(key));
+            return mgr.CreateOne(new CreateIndexModel<T>(asc ? Builders<T>.IndexKeys.Ascending(key) : Builders<T>.IndexKeys.Descending(key)));
         }
 
         /// <summary>
@@ -1171,7 +1171,7 @@ namespace Masuit.Tools.NoSQL.MongoDBClient
         public async Task<string> UpdateIndexAsync<T>(string collection, Expression<Func<T, object>> key, bool asc = true)
         {
             IMongoIndexManager<T> mgr = Database.GetCollection<T>(collection).Indexes;
-            return await mgr.CreateOneAsync(asc ? Builders<T>.IndexKeys.Ascending(key) : Builders<T>.IndexKeys.Descending(key));
+            return await mgr.CreateOneAsync(new CreateIndexModel<T>(asc ? Builders<T>.IndexKeys.Ascending(key) : Builders<T>.IndexKeys.Descending(key)));
         }
 
         #endregion

+ 2 - 2
Masuit.Tools.NoSQL.MongoDBClient/Masuit.Tools.NoSQL.MongoDBClient.csproj

@@ -53,8 +53,8 @@
     <Reference Include="MongoDB.Driver.Core, Version=2.7.2.0, Culture=neutral, processorArchitecture=MSIL">
       <HintPath>..\packages\MongoDB.Driver.Core.2.7.2\lib\net45\MongoDB.Driver.Core.dll</HintPath>
     </Reference>
-    <Reference Include="Newtonsoft.Json, Version=11.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
-      <HintPath>..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
+    <Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
+      <HintPath>..\packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
     </Reference>
     <Reference Include="StackExchange.Redis, Version=1.2.6.0, Culture=neutral, processorArchitecture=MSIL">
       <HintPath>..\packages\StackExchange.Redis.1.2.6\lib\net45\StackExchange.Redis.dll</HintPath>

+ 17 - 9
Masuit.Tools.NoSQL.MongoDBClient/MongoDbClient.cs

@@ -12,9 +12,18 @@ using System.Threading.Tasks;
 
 namespace Masuit.Tools.NoSQL.MongoDBClient
 {
+    /// <summary>
+    /// MongoDB客户端类
+    /// </summary>
     public class MongoDbClient
     {
+        /// <summary>
+        /// 客户端对象
+        /// </summary>
         public MongoClient Client { get; set; }
+        /// <summary>
+        /// 数据库对象
+        /// </summary>
         public IMongoDatabase Database { get; set; }
         private static ConcurrentDictionary<string, MongoDbClient> InstancePool { get; set; } = new ConcurrentDictionary<string, MongoDbClient>();
         private static ConcurrentDictionary<string, ConcurrentLimitedQueue<MongoDbClient>> InstanceQueue { get; set; } = new ConcurrentDictionary<string, ConcurrentLimitedQueue<MongoDbClient>>();
@@ -50,7 +59,6 @@ namespace Masuit.Tools.NoSQL.MongoDBClient
         /// <summary>
         /// 获取mongo默认单例
         /// </summary>
-        /// <param name="url">连接字符串</param>
         /// <param name="database">数据库</param>
         /// <returns></returns>
         public static MongoDbClient GetDefaultInstance(string database)
@@ -1049,7 +1057,7 @@ namespace Masuit.Tools.NoSQL.MongoDBClient
             {
                 if (!list.Current.Any(doc => doc["name"].AsString.StartsWith(index)))
                 {
-                    return mgr.CreateOne(asc ? Builders<BsonDocument>.IndexKeys.Ascending(doc => doc[index]) : Builders<BsonDocument>.IndexKeys.Descending(doc => doc[index]));
+                    return mgr.CreateOne(new CreateIndexModel<BsonDocument>(asc ? Builders<BsonDocument>.IndexKeys.Ascending(doc => doc[index]) : Builders<BsonDocument>.IndexKeys.Descending(doc => doc[index])));
                 }
             }
             return string.Empty;
@@ -1070,7 +1078,7 @@ namespace Masuit.Tools.NoSQL.MongoDBClient
             {
                 if (!list.Current.Any(doc => doc["name"].AsString.StartsWith(index)))
                 {
-                    return await mgr.CreateOneAsync(asc ? Builders<BsonDocument>.IndexKeys.Ascending(doc => doc[index]) : Builders<BsonDocument>.IndexKeys.Descending(doc => doc[index]));
+                    return await mgr.CreateOneAsync(new CreateIndexModel<BsonDocument>(asc ? Builders<BsonDocument>.IndexKeys.Ascending(doc => doc[index]) : Builders<BsonDocument>.IndexKeys.Descending(doc => doc[index])));
                 }
             }
             return string.Empty;
@@ -1086,7 +1094,7 @@ namespace Masuit.Tools.NoSQL.MongoDBClient
         public string UpdateIndex(string collection, string index, bool asc = true)
         {
             IMongoIndexManager<BsonDocument> mgr = Database.GetCollection<BsonDocument>(collection).Indexes;
-            return mgr.CreateOne(asc ? Builders<BsonDocument>.IndexKeys.Ascending(doc => doc[index]) : Builders<BsonDocument>.IndexKeys.Descending(doc => doc[index]));
+            return mgr.CreateOne(new CreateIndexModel<BsonDocument>(asc ? Builders<BsonDocument>.IndexKeys.Ascending(doc => doc[index]) : Builders<BsonDocument>.IndexKeys.Descending(doc => doc[index])));
         }
 
         /// <summary>
@@ -1099,7 +1107,7 @@ namespace Masuit.Tools.NoSQL.MongoDBClient
         public async Task<string> UpdateIndexAsync(string collection, string index, bool asc = true)
         {
             IMongoIndexManager<BsonDocument> mgr = Database.GetCollection<BsonDocument>(collection).Indexes;
-            return await mgr.CreateOneAsync(asc ? Builders<BsonDocument>.IndexKeys.Ascending(doc => doc[index]) : Builders<BsonDocument>.IndexKeys.Descending(doc => doc[index]));
+            return await mgr.CreateOneAsync(new CreateIndexModel<BsonDocument>(asc ? Builders<BsonDocument>.IndexKeys.Ascending(doc => doc[index]) : Builders<BsonDocument>.IndexKeys.Descending(doc => doc[index])));
         }
 
         /// <summary>
@@ -1140,7 +1148,7 @@ namespace Masuit.Tools.NoSQL.MongoDBClient
             {
                 if (!list.Current.Any(doc => doc["name"].AsString.StartsWith(index)))
                 {
-                    return mgr.CreateOne(asc ? Builders<T>.IndexKeys.Ascending(key) : Builders<T>.IndexKeys.Descending(key));
+                    return mgr.CreateOne(new CreateIndexModel<T>(asc ? Builders<T>.IndexKeys.Ascending(key) : Builders<T>.IndexKeys.Descending(key)));
                 }
             }
             return String.Empty;
@@ -1162,7 +1170,7 @@ namespace Masuit.Tools.NoSQL.MongoDBClient
             {
                 if (!list.Current.Any(doc => doc["name"].AsString.StartsWith(index)))
                 {
-                    return await mgr.CreateOneAsync(asc ? Builders<T>.IndexKeys.Ascending(key) : Builders<T>.IndexKeys.Descending(key));
+                    return await mgr.CreateOneAsync(new CreateIndexModel<T>(asc ? Builders<T>.IndexKeys.Ascending(key) : Builders<T>.IndexKeys.Descending(key)));
                 }
             }
             return String.Empty;
@@ -1178,7 +1186,7 @@ namespace Masuit.Tools.NoSQL.MongoDBClient
         public string UpdateIndex<T>(string collection, Expression<Func<T, object>> key, bool asc = true)
         {
             IMongoIndexManager<T> mgr = Database.GetCollection<T>(collection).Indexes;
-            return mgr.CreateOne(asc ? Builders<T>.IndexKeys.Ascending(key) : Builders<T>.IndexKeys.Descending(key));
+            return mgr.CreateOne(new CreateIndexModel<T>(asc ? Builders<T>.IndexKeys.Ascending(key) : Builders<T>.IndexKeys.Descending(key)));
         }
 
         /// <summary>
@@ -1191,7 +1199,7 @@ namespace Masuit.Tools.NoSQL.MongoDBClient
         public async Task<string> UpdateIndexAsync<T>(string collection, Expression<Func<T, object>> key, bool asc = true)
         {
             IMongoIndexManager<T> mgr = Database.GetCollection<T>(collection).Indexes;
-            return await mgr.CreateOneAsync(asc ? Builders<T>.IndexKeys.Ascending(key) : Builders<T>.IndexKeys.Descending(key));
+            return await mgr.CreateOneAsync(new CreateIndexModel<T>(asc ? Builders<T>.IndexKeys.Ascending(key) : Builders<T>.IndexKeys.Descending(key)));
         }
 
         #endregion

+ 1 - 1
Masuit.Tools.NoSQL.MongoDBClient/packages.config

@@ -6,7 +6,7 @@
   <package id="MongoDB.Bson" version="2.7.2" targetFramework="net45" />
   <package id="MongoDB.Driver" version="2.7.2" targetFramework="net45" />
   <package id="MongoDB.Driver.Core" version="2.7.2" targetFramework="net45" />
-  <package id="Newtonsoft.Json" version="11.0.2" targetFramework="net45" />
+  <package id="Newtonsoft.Json" version="12.0.1" targetFramework="net45" />
   <package id="SharpZipLib" version="1.0.0" targetFramework="net45" />
   <package id="StackExchange.Redis" version="1.2.6" targetFramework="net45" />
   <package id="System.Buffers" version="4.4.0" targetFramework="net45" />

+ 1 - 0
Masuit.Tools.UnitTest/Masuit.Tools.UnitTest.csproj

@@ -66,6 +66,7 @@
     <Compile Include="ChineseCalendarTest.cs" />
     <Compile Include="ExtensionMethodsTest.cs" />
     <Compile Include="HtmlToolsTest.cs" />
+    <Compile Include="NumberFormaterTest.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="TemplateTest.cs" />
   </ItemGroup>

+ 34 - 0
Masuit.Tools.UnitTest/NumberFormaterTest.cs

@@ -0,0 +1,34 @@
+using Masuit.Tools.Strings;
+using Xunit;
+
+namespace Masuit.Tools.UnitTest
+{
+    public class NumberFormaterTest
+    {
+        [Theory]
+        [InlineData(2, 16, "10000")]
+        [InlineData(8, 8, "10")]
+        [InlineData(16, 16, "10")]
+        [InlineData(36, 36, "10")]
+        [InlineData(62, 62, "10")]
+        public void Can_ConvertOct2AnySystem(int bin, long input, string expectOutput)
+        {
+            var nf = new NumberFormater(bin);
+            string output = nf.ToString(input);
+            Assert.Equal(expectOutput, output);
+        }
+
+        [Theory]
+        [InlineData(2, "10000", 16)]
+        [InlineData(8, "10", 8)]
+        [InlineData(16, "10", 16)]
+        [InlineData(36, "10", 36)]
+        [InlineData(62, "10", 62)]
+        public void Can_ConvertAnySystem2Oct(int bin, string input, long expected)
+        {
+            var nf = new NumberFormater(bin);
+            string output = nf.ToString(expected);
+            Assert.Equal(input, output);
+        }
+    }
+}

+ 1 - 0
Masuit.Tools.UnitTest/TemplateTest.cs

@@ -1,6 +1,7 @@
 using Masuit.Tools.Strings;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using System;
+using Assert = Microsoft.VisualStudio.TestTools.UnitTesting.Assert;
 
 namespace Masuit.Tools.UnitTest
 {

+ 14 - 3
Masuit.Tools/DateTimeExt/ChineseCalendar.cs

@@ -966,6 +966,7 @@ namespace Masuit.Tools.DateTimeExt
                         tempStr = sh.HolidayName;
                         break;
                     }
+
                     if (CustomHolidays.Keys.Any(d => d.Date == _date))
                     {
                         tempStr = CustomHolidays[_date];
@@ -977,8 +978,14 @@ namespace Masuit.Tools.DateTimeExt
             }
         }
 
+        /// <summary>
+        /// 今天是否是假期
+        /// </summary>
         public bool IsHoliday => !IsWorkDay;
 
+        /// <summary>
+        /// 今天是否是工作日
+        /// </summary>
         public bool IsWorkDay
         {
             get
@@ -1191,7 +1198,7 @@ namespace Masuit.Tools.DateTimeExt
         }
 
         /// <summary>
-        /// 取农历日期表示法:一九九七年正月初五
+        /// 取农历日期表示法:农历一九九七年正月初五
         /// </summary>
         public string ChineseDateString
         {
@@ -1241,7 +1248,9 @@ namespace Masuit.Tools.DateTimeExt
             }
         }
 
-        //当前日期前一个最近节气
+        /// <summary>
+        /// 当前日期前一个最近节气
+        /// </summary>
         public string ChineseTwentyFourPrevDay
         {
             get
@@ -1264,7 +1273,9 @@ namespace Masuit.Tools.DateTimeExt
             }
         }
 
-        //当前日期后一个最近节气
+        /// <summary>
+        /// 当前日期后一个最近节气
+        /// </summary>
         public string ChineseTwentyFourNextDay
         {
             get

+ 26 - 1
Masuit.Tools/DateTimeExt/DateInfoStruct.cs

@@ -1,12 +1,37 @@
 namespace Masuit.Tools.DateTimeExt
 {
+    /// <summary>
+    /// 日期信息
+    /// </summary>
     public struct DateInfoStruct
     {
+        /// <summary>
+        /// 月
+        /// </summary>
         public readonly int Month;
+
+        /// <summary>
+        /// 日
+        /// </summary>
         public readonly int Day;
-        public readonly int Recess; //假期长度
+
+        /// <summary>
+        /// 假期长度
+        /// </summary>
+        public readonly int Recess;
+
+        /// <summary>
+        /// 节假日名
+        /// </summary>
         public readonly string HolidayName;
 
+        /// <summary>
+        /// 日期信息
+        /// </summary>
+        /// <param name="month"></param>
+        /// <param name="day"></param>
+        /// <param name="recess"></param>
+        /// <param name="name"></param>
         public DateInfoStruct(int month, int day, int recess, string name)
         {
             Month = month;

+ 25 - 0
Masuit.Tools/DateTimeExt/WeekHolidayStruct.cs

@@ -1,12 +1,37 @@
 namespace Masuit.Tools.DateTimeExt
 {
+    /// <summary>
+    /// 节假日信息
+    /// </summary>
     public struct WeekHolidayStruct
     {
+        /// <summary>
+        /// 月
+        /// </summary>
         public readonly int Month;
+
+        /// <summary>
+        /// 这个月第几周
+        /// </summary>
         public readonly int WeekAtMonth;
+
+        /// <summary>
+        /// 周末日
+        /// </summary>
         public readonly int WeekDay;
+
+        /// <summary>
+        /// 假日名
+        /// </summary>
         public readonly string HolidayName;
 
+        /// <summary>
+        /// 节假日信息
+        /// </summary>
+        /// <param name="month"></param>
+        /// <param name="weekAtMonth"></param>
+        /// <param name="weekDay"></param>
+        /// <param name="name"></param>
         public WeekHolidayStruct(int month, int weekAtMonth, int weekDay, string name)
         {
             Month = month;

+ 6 - 6
Masuit.Tools/Linq/LinqExtension.cs

@@ -1,10 +1,10 @@
 using System;
 using System.Linq.Expressions;
 
-namespace Masuit.Tools.Linq
+namespace Masuit.Tools.Core.Linq
 {
     /// <summary>
-    /// linq扩展
+    /// linq扩展
     /// </summary>
     public static class LinqExtension
     {
@@ -12,8 +12,8 @@ namespace Masuit.Tools.Linq
         /// 与连接
         /// </summary>
         /// <typeparam name="T"></typeparam>
-        /// <param name="left"></param>
-        /// <param name="right"></param>
+        /// <param name="left">左条件</param>
+        /// <param name="right">右条件</param>
         /// <returns></returns>
         public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> left, Expression<Func<T, bool>> right)
         {
@@ -29,8 +29,8 @@ namespace Masuit.Tools.Linq
         /// 或连接
         /// </summary>
         /// <typeparam name="T"></typeparam>
-        /// <param name="left"></param>
-        /// <param name="right"></param>
+        /// <param name="left">左条件</param>
+        /// <param name="right">右条件</param>
         /// <returns></returns>
         public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> left, Expression<Func<T, bool>> right)
         {

+ 13 - 5
Masuit.Tools/Linq/ParameterReplacer.cs

@@ -1,24 +1,28 @@
 using System.Linq.Expressions;
 
-namespace Masuit.Tools.Linq
+namespace Masuit.Tools.Core.Linq
 {
     /// <summary>
-    /// 表达式树参数替换
+    /// linq参数替换器
     /// </summary>
     public class ParameterReplacer : ExpressionVisitor
     {
+        /// <summary>
+        /// linq参数替换器
+        /// </summary>
+        /// <param name="paramExpr"></param>
         public ParameterReplacer(ParameterExpression paramExpr)
         {
             this.ParameterExpression = paramExpr;
         }
 
         /// <summary>
-        /// 参数表达式
+        /// 参数表达式
         /// </summary>
         public ParameterExpression ParameterExpression { get; private set; }
 
         /// <summary>
-        /// 替换表达式树
+        /// 表达式替换
         /// </summary>
         /// <param name="expr"></param>
         /// <returns></returns>
@@ -26,7 +30,11 @@ namespace Masuit.Tools.Linq
         {
             return this.Visit(expr);
         }
-
+        /// <summary>
+        /// 表达式参数访问
+        /// </summary>
+        /// <param name="p"></param>
+        /// <returns></returns>
         protected override Expression VisitParameter(ParameterExpression p)
         {
             return this.ParameterExpression;

+ 22 - 1
Masuit.Tools/Logging/LogLevel.cs

@@ -1,7 +1,28 @@
 namespace Masuit.Tools.Logging
 {
+    /// <summary>
+    /// 日志级别
+    /// </summary>
     public enum LogLevel
     {
-        Info, Debug, Error, Fatal
+        /// <summary>
+        /// 信息级别
+        /// </summary>
+        Info,
+
+        /// <summary>
+        /// debug级别
+        /// </summary>
+        Debug,
+
+        /// <summary>
+        /// 错误级别
+        /// </summary>
+        Error,
+
+        /// <summary>
+        /// 致命级别
+        /// </summary>
+        Fatal
     }
 }

+ 6 - 4
Masuit.Tools/Masuit.Tools.csproj

@@ -39,17 +39,17 @@
   </PropertyGroup>
   <ItemGroup>
     <Reference Include="AngleSharp, Version=0.9.9.0, Culture=neutral, PublicKeyToken=e83494dcdc6d31ea, processorArchitecture=MSIL">
-      <HintPath>..\..\MyBlogs\packages\AngleSharp.0.9.11\lib\net45\AngleSharp.dll</HintPath>
+      <HintPath>..\packages\AngleSharp.0.9.11\lib\net45\AngleSharp.dll</HintPath>
     </Reference>
     <Reference Include="HtmlSanitizer, Version=3.0.0.0, Culture=neutral, PublicKeyToken=61c49a1a9e79cc28, processorArchitecture=MSIL">
-      <HintPath>..\..\MyBlogs\packages\HtmlSanitizer.4.0.199\lib\net45\HtmlSanitizer.dll</HintPath>
+      <HintPath>..\packages\HtmlSanitizer.4.0.199\lib\net45\HtmlSanitizer.dll</HintPath>
     </Reference>
     <Reference Include="ICSharpCode.SharpZipLib, Version=1.0.0.999, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
-      <HintPath>..\..\MyBlogs\packages\SharpZipLib.1.0.0\lib\net45\ICSharpCode.SharpZipLib.dll</HintPath>
+      <HintPath>..\packages\SharpZipLib.1.0.0\lib\net45\ICSharpCode.SharpZipLib.dll</HintPath>
     </Reference>
     <Reference Include="Microsoft.CSharp" />
     <Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
-      <HintPath>..\..\MyBlogs\packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+      <HintPath>..\packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
     </Reference>
     <Reference Include="StackExchange.Redis, Version=1.2.6.0, Culture=neutral, processorArchitecture=MSIL">
       <HintPath>..\packages\StackExchange.Redis.1.2.6\lib\net45\StackExchange.Redis.dll</HintPath>
@@ -118,9 +118,11 @@
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Security\HashEncode.cs" />
     <Compile Include="Security\RSACrypt.cs" />
+    <Compile Include="Strings\NumberFormater.cs" />
     <Compile Include="Strings\Template.cs" />
     <Compile Include="Systems\ConcurrentLimitedQueue.cs" />
     <Compile Include="Systems\Disposable.cs" />
+    <Compile Include="Systems\HiPerfTimer.cs" />
     <Compile Include="Systems\LimitedQueue.cs" />
     <Compile Include="Strings\ValidateCode.cs" />
     <Compile Include="Net\WebExtension.cs" />

+ 3 - 0
Masuit.Tools/Net/FtpClient.cs

@@ -29,6 +29,9 @@ namespace Masuit.Tools.Net
         /// </summary>
         public static string Password { get; set; }
 
+        /// <summary>
+        /// ftp地址
+        /// </summary>
         public static string FtpUri = "ftp://" + FtpServer + "/";
 
         #endregion

+ 74 - 2
Masuit.Tools/Net/MultiThreadDownloader.cs

@@ -39,6 +39,13 @@ namespace Masuit.Tools.Net
 
         #region 下载管理器
 
+        /// <summary>
+        /// 多线程下载管理器
+        /// </summary>
+        /// <param name="sourceUrl"></param>
+        /// <param name="tempDir"></param>
+        /// <param name="savePath"></param>
+        /// <param name="numOfParts"></param>
         public MultiThreadDownloader(string sourceUrl, string tempDir, string savePath, int numOfParts)
         {
             _url = sourceUrl;
@@ -49,11 +56,22 @@ namespace Masuit.Tools.Net
             FilePath = savePath;
         }
 
+        /// <summary>
+        /// 多线程下载管理器
+        /// </summary>
+        /// <param name="sourceUrl"></param>
+        /// <param name="savePath"></param>
+        /// <param name="numOfParts"></param>
         public MultiThreadDownloader(string sourceUrl, string savePath, int numOfParts) : this(sourceUrl, null, savePath, numOfParts)
         {
             TempFileDirectory = Environment.GetEnvironmentVariable("temp");
         }
 
+        /// <summary>
+        /// 多线程下载管理器
+        /// </summary>
+        /// <param name="sourceUrl"></param>
+        /// <param name="numOfParts"></param>
         public MultiThreadDownloader(string sourceUrl, int numOfParts) : this(sourceUrl, null, numOfParts)
         {
         }
@@ -184,6 +202,11 @@ namespace Masuit.Tools.Net
             return new PartialDownloader(_url, TempFileDirectory, Guid.NewGuid().ToString(), start, end, true);
         }
 
+        /// <summary>
+        /// 暂停或继续
+        /// </summary>
+        /// <param name="list"></param>
+        /// <param name="wait"></param>
         public static void WaitOrResumeAll(List<PartialDownloader> list, bool wait)
         {
             foreach (PartialDownloader item in list)
@@ -195,7 +218,10 @@ namespace Masuit.Tools.Net
             }
         }
 
-
+        /// <summary>
+        /// 冒泡排序
+        /// </summary>
+        /// <param name="list"></param>
         private static void BubbleSort(List<PartialDownloader> list)
         {
             bool switched = true;
@@ -215,17 +241,32 @@ namespace Masuit.Tools.Net
             }
         }
 
-        //Sorts the downloader by From property to merge the parts
+        /// <summary>
+        /// Sorts the downloader by From property to merge the parts
+        /// </summary>
+        /// <param name="list"></param>
+        /// <returns></returns>
         public static List<PartialDownloader> SortPDsByFrom(List<PartialDownloader> list)
         {
             return list.OrderBy(x => x.From).ToList();
         }
 
+        /// <summary>
+        /// 按剩余时间排序
+        /// </summary>
+        /// <param name="list"></param>
         public static void OrderByRemaining(List<PartialDownloader> list)
         {
             BubbleSort(list);
         }
 
+        /// <summary>
+        /// 获取内容长度
+        /// </summary>
+        /// <param name="url"></param>
+        /// <param name="rangeAllowed"></param>
+        /// <param name="redirectedUrl"></param>
+        /// <returns></returns>
         public static long GetContentLength(string url, ref bool rangeAllowed, ref string redirectedUrl)
         {
             HttpWebRequest req = WebRequest.Create(url) as HttpWebRequest;
@@ -311,31 +352,62 @@ namespace Masuit.Tools.Net
 
         #region 公共属性
 
+        /// <summary>
+        /// RangeAllowed
+        /// </summary>
         public bool RangeAllowed
         {
             get => _rangeAllowed;
             set => _rangeAllowed = value;
         }
 
+        /// <summary>
+        /// 临时文件夹
+        /// </summary>
         public string TempFileDirectory { get; set; }
 
+        /// <summary>
+        /// url地址
+        /// </summary>
         public string Url
         {
             get => _url;
             set => _url = value;
         }
 
+        /// <summary>
+        /// 第几部分
+        /// </summary>
         public int NumberOfParts { get; set; }
 
+        /// <summary>
+        /// 已接收字节数
+        /// </summary>
         public long TotalBytesReceived => PartialDownloaderList.Where(t => t != null).Sum(t => t.TotalBytesRead);
 
+        /// <summary>
+        /// 总进度
+        /// </summary>
         public int TotalProgress { get; private set; }
 
+        /// <summary>
+        /// 文件大小
+        /// </summary>
         public long Size { get; private set; }
 
+        /// <summary>
+        /// 下载速度
+        /// </summary>
         public int TotalSpeedInBytes => PartialDownloaderList.Sum(t => t.SpeedInBytes);
+
+        /// <summary>
+        /// 下载块
+        /// </summary>
         public List<PartialDownloader> PartialDownloaderList { get; }
 
+        /// <summary>
+        /// 文件路径
+        /// </summary>
         public string FilePath { get; set; }
 
         #endregion

+ 85 - 5
Masuit.Tools/Net/PartialDownloader.cs

@@ -8,13 +8,28 @@ using System.Threading;
 
 namespace Masuit.Tools.Net
 {
+    /// <summary>
+    /// 部分下载器
+    /// </summary>
     public class PartialDownloader
     {
         #region Variables
 
+        /// <summary>
+        /// 这部分完成事件
+        /// </summary>
         public event EventHandler DownloadPartCompleted;
+
+        /// <summary>
+        /// 部分下载进度改变事件
+        /// </summary>
         public event EventHandler DownloadPartProgressChanged;
+
+        /// <summary>
+        /// 部分下载停止事件
+        /// </summary>
         public event EventHandler DownloadPartStopped;
+
         HttpWebRequest _req;
         HttpWebResponse _resp;
         Stream _tempStream;
@@ -29,6 +44,15 @@ namespace Masuit.Tools.Net
 
         #region PartialDownloader
 
+        /// <summary>
+        /// 部分块下载
+        /// </summary>
+        /// <param name="url"></param>
+        /// <param name="dir"></param>
+        /// <param name="fileGuid"></param>
+        /// <param name="from"></param>
+        /// <param name="to"></param>
+        /// <param name="rangeAllowed"></param>
         public PartialDownloader(string url, string dir, string fileGuid, int from, int to, bool rangeAllowed)
         {
             _from = from;
@@ -89,12 +113,12 @@ namespace Masuit.Tools.Net
                         }
 
                         if (_totalBytesRead + bytesRead > _contentLength)
-                            bytesRead = (int) (_contentLength - _totalBytesRead);
+                            bytesRead = (int)(_contentLength - _totalBytesRead);
                         _file.Write(buffer, 0, bytesRead);
                         _totalBytesRead += bytesRead;
-                        _lastSpeeds[_counter] = (int) (_totalBytesRead / Math.Ceiling(_stp.Elapsed.TotalSeconds));
+                        _lastSpeeds[_counter] = (int)(_totalBytesRead / Math.Ceiling(_stp.Elapsed.TotalSeconds));
                         _counter = (_counter >= 9) ? 0 : _counter + 1;
-                        int tempProgress = (int) (_totalBytesRead * 100 / _contentLength);
+                        int tempProgress = (int)(_totalBytesRead * 100 / _contentLength);
                         if (_progress != tempProgress)
                         {
                             _progress = tempProgress;
@@ -143,6 +167,9 @@ namespace Masuit.Tools.Net
 
         #region Public Methods
 
+        /// <summary>
+        /// 启动下载
+        /// </summary>
         public void Start()
         {
             _stop = false;
@@ -150,17 +177,25 @@ namespace Masuit.Tools.Net
             procThread.Start();
         }
 
+        /// <summary>
+        /// 下载停止
+        /// </summary>
         public void Stop()
         {
             _stop = true;
         }
 
-        //Wait is used when repartitiate a partition securely in this project
+        /// <summary>
+        /// 暂停等待下载
+        /// </summary>
         public void Wait()
         {
             _wait = true;
         }
 
+        /// <summary>
+        /// 稍后唤醒
+        /// </summary>
         public void ResumeAfterWait()
         {
             _wait = false;
@@ -185,24 +220,54 @@ namespace Masuit.Tools.Net
 
         #region Properties
 
+        /// <summary>
+        /// 下载已停止
+        /// </summary>
         public bool Stopped => _stop;
 
+        /// <summary>
+        /// 下载已完成
+        /// </summary>
         public bool Completed => _completed;
 
+        /// <summary>
+        /// 下载进度
+        /// </summary>
         public int Progress => _progress;
 
+        /// <summary>
+        /// 下载目录
+        /// </summary>
         public string Directory => _directory;
 
+        /// <summary>
+        /// 文件名
+        /// </summary>
         public string FileName => _fileGuid;
 
+        /// <summary>
+        /// 已读字节数
+        /// </summary>
         public long TotalBytesRead => _totalBytesRead;
 
+        /// <summary>
+        /// 内容长度
+        /// </summary>
         public long ContentLength => _contentLength;
 
+        /// <summary>
+        /// RangeAllowed
+        /// </summary>
         public bool RangeAllowed => _rangeAllowed;
 
+        /// <summary>
+        /// url
+        /// </summary>
         public string Url => _url;
 
+        /// <summary>
+        /// to
+        /// </summary>
         public int To
         {
             get => _to;
@@ -213,14 +278,29 @@ namespace Masuit.Tools.Net
             }
         }
 
+        /// <summary>
+        /// from
+        /// </summary>
         public int From => _from;
 
+        /// <summary>
+        /// 当前位置
+        /// </summary>
         public int CurrentPosition => _from + _totalBytesRead - 1;
 
-        public int RemainingBytes => (int) (_contentLength - _totalBytesRead);
+        /// <summary>
+        /// 剩余字节数
+        /// </summary>
+        public int RemainingBytes => (int)(_contentLength - _totalBytesRead);
 
+        /// <summary>
+        /// 完整路径
+        /// </summary>
         public string FullPath => Path.Combine(_directory, _fileGuid);
 
+        /// <summary>
+        /// 下载速度
+        /// </summary>
         public int SpeedInBytes
         {
             get

+ 2 - 2
Masuit.Tools/Properties/AssemblyInfo.cs

@@ -36,7 +36,7 @@ using System.Runtime.InteropServices;
 // 方法是按如下所示使用“*”: :
 // [assembly: AssemblyVersion("1.0.*")]
 
-[assembly: AssemblyVersion("2.1.4.3")]
-[assembly: AssemblyFileVersion("2.1.4.3")]
+[assembly: AssemblyVersion("2.1.5.0")]
+[assembly: AssemblyFileVersion("2.1.5.0")]
 [assembly: NeutralResourcesLanguage("zh-CN")]
 

+ 103 - 0
Masuit.Tools/Strings/NumberFormater.cs

@@ -0,0 +1,103 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Masuit.Tools.Strings
+{
+    /// <summary>
+    /// 数制格式化器
+    /// </summary>
+    public class NumberFormater
+    {
+        /// <summary>
+        /// 数制表示字符集
+        /// </summary>
+        private string Characters { get; set; }
+
+        /// <summary>
+        /// 进制长度
+        /// </summary>
+        public int Length => Characters?.Length ?? 0;
+
+        public NumberFormater()
+        {
+            Characters = "0123456789";
+        }
+
+        /// <summary>
+        /// 数制格式化器
+        /// </summary>
+        /// <param name="characters">进制转换</param>
+        public NumberFormater(string characters)
+        {
+            Characters = characters;
+        }
+
+        /// <summary>
+        /// 数制格式化器
+        /// </summary>
+        /// <param name="bin">进制</param>
+        public NumberFormater(int bin)
+        {
+            if (bin < 2)
+            {
+                bin = 2;
+            }
+
+            if (bin > 62)
+            {
+                throw new ArgumentException("进制最大支持62进制");
+            }
+            Characters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".Substring(0, bin);
+        }
+
+        /// <summary>
+        /// 数字转换为指定的进制形式字符串
+        /// </summary>
+        /// <param name="number"></param>
+        /// <returns></returns>
+        public string ToString(long number)
+        {
+            List<string> result = new List<string>();
+            long t = number;
+
+            while (t > 0)
+            {
+                var mod = t % Length;
+                t = Math.Abs(t / Length);
+                var character = Characters[Convert.ToInt32(mod)].ToString();
+                result.Insert(0, character);
+            }
+
+            return string.Join("", result.ToArray());
+        }
+
+        /// <summary>
+        /// 指定字符串转换为指定进制的数字形式
+        /// </summary>
+        /// <param name="str"></param>
+        /// <returns></returns>
+        public long FromString(string str)
+        {
+            long result = 0;
+            int j = 0;
+            foreach (var ch in new string(str.ToCharArray().Reverse().ToArray()))
+            {
+                if (Characters.Contains(ch))
+                {
+                    result += Characters.IndexOf(ch) * (long)Math.Pow(Length, j);
+                    j++;
+                }
+            }
+
+            return result;
+        }
+
+        /// <summary>Returns a string that represents the current object.</summary>
+        /// <returns>A string that represents the current object.</returns>
+        public override string ToString()
+        {
+            return Length + "模式";
+        }
+    }
+}

+ 18 - 1
Masuit.Tools/Strings/Template.cs

@@ -3,21 +3,38 @@ using System.Text.RegularExpressions;
 
 namespace Masuit.Tools.Strings
 {
+    /// <summary>
+    /// 模版引擎
+    /// </summary>
     public class Template
     {
         private string Content { get; set; }
 
+        /// <summary>
+        /// 模版引擎
+        /// </summary>
+        /// <param name="content"></param>
         public Template(string content)
         {
             Content = content;
         }
 
+        /// <summary>
+        /// 设置变量
+        /// </summary>
+        /// <param name="key"></param>
+        /// <param name="value"></param>
+        /// <returns></returns>
         public Template Set(string key, string value)
         {
             Content = Content.Replace("{{" + key + "}}", value);
             return this;
         }
 
+        /// <summary>
+        /// 渲染模板
+        /// </summary>
+        /// <returns></returns>
         public string Render()
         {
             var mc = Regex.Matches(Content, @"\{\{.+?\}\}");
@@ -25,8 +42,8 @@ namespace Masuit.Tools.Strings
             {
                 throw new ArgumentException($"模版变量{m.Value}未被使用");
             }
+
             return Content;
         }
-
     }
 }

+ 15 - 0
Masuit.Tools/Systems/ConcurrentLimitedQueue.cs

@@ -10,18 +10,33 @@ namespace Masuit.Tools.Systems
     /// <typeparam name="T"></typeparam>
     public class ConcurrentLimitedQueue<T> : ConcurrentQueue<T>
     {
+        /// <summary>
+        /// 长度
+        /// </summary>
         public int Limit { get; set; }
 
+        /// <summary>
+        /// 定长队列
+        /// </summary>
+        /// <param name="limit"></param>
         public ConcurrentLimitedQueue(int limit)
         {
             Limit = limit;
         }
 
+        /// <summary>
+        /// 定长队列
+        /// </summary>
+        /// <param name="list"></param>
         public ConcurrentLimitedQueue(IEnumerable<T> list) : base(list)
         {
             Limit = list.Count();
         }
 
+        /// <summary>
+        /// 入队
+        /// </summary>
+        /// <param name="item"></param>
         public new void Enqueue(T item)
         {
             if (Count >= Limit)

+ 15 - 2
Masuit.Tools/Systems/Disposable.cs

@@ -2,26 +2,39 @@
 
 namespace Masuit.Tools.Systems
 {
+    /// <summary>
+    /// Disposable
+    /// </summary>
     public abstract class Disposable : IDisposable
     {
         private bool isDisposed;
 
+        /// <summary>
+        /// 终结器
+        /// </summary>
         ~Disposable()
         {
             Dispose(false);
         }
 
+        /// <summary>
+        /// 
+        /// </summary>
         public void Dispose()
         {
             if (isDisposed)
             {
                 return;
             }
+
             Dispose(true);
             isDisposed = true;
             GC.SuppressFinalize(this);
         }
-
+        /// <summary>
+        /// 释放
+        /// </summary>
+        /// <param name="disposing"></param>
         public abstract void Dispose(bool disposing);
     }
-}
+}

+ 4 - 4
Masuit.Tools/Systems/EnumExt.cs

@@ -42,7 +42,7 @@ namespace Masuit.Tools.Systems
             Dictionary<int, string> names = new Dictionary<int, string>(enumItems.Length);
             foreach (FieldInfo enumItem in enumItems)
             {
-                int intValue = (int) enumItem.GetValue(enumType);
+                int intValue = (int)enumItem.GetValue(enumType);
                 names[intValue] = enumItem.Name;
             }
 
@@ -73,7 +73,7 @@ namespace Masuit.Tools.Systems
             Dictionary<string, int> values = new Dictionary<string, int>(enumItems.Length);
             foreach (FieldInfo enumItem in enumItems)
             {
-                values[enumItem.Name] = (int) enumItem.GetValue(enumType);
+                values[enumItem.Name] = (int)enumItem.GetValue(enumType);
             }
 
             return values;
@@ -127,7 +127,7 @@ namespace Masuit.Tools.Systems
             Dictionary<string, int> dicResult = new Dictionary<string, int>();
             foreach (object e in Enum.GetValues(enumType))
             {
-                dicResult.Add(GetDescription(e as Enum), (int) e);
+                dicResult.Add(GetDescription(e as Enum), (int)e);
             }
 
             return dicResult;
@@ -198,7 +198,7 @@ namespace Masuit.Tools.Systems
             {
                 if (field.FieldType.IsEnum)
                 {
-                    var strValue = ((int) enumType.InvokeMember(field.Name, BindingFlags.GetField, null, null, null)).ToString();
+                    var strValue = ((int)enumType.InvokeMember(field.Name, BindingFlags.GetField, null, null, null)).ToString();
                     nvc.Add(strValue, field.Name);
                 }
             }

+ 72 - 0
Masuit.Tools/Systems/HiPerfTimer.cs

@@ -0,0 +1,72 @@
+using System;
+using System.ComponentModel;
+using System.Runtime.InteropServices;
+using System.Threading;
+
+namespace Masuit.Tools.Systems
+{
+    public class HiPerfTimer
+    {
+        [DllImport("Kernel32.dll")]
+        private static extern bool QueryPerformanceCounter(out long lpPerformanceCount);
+
+        [DllImport("Kernel32.dll")]
+        private static extern bool QueryPerformanceFrequency(out long lpFrequency);
+
+        private long _startTime;
+        private long _stopTime;
+        private readonly long _freq;
+
+        // 构造函数 
+        public HiPerfTimer()
+        {
+            _startTime = 0;
+            _stopTime = 0;
+
+            if (QueryPerformanceFrequency(out _freq) == false)
+            {
+                // 不支持高性能计数器 
+                throw new Win32Exception();
+            }
+        }
+
+        // 开始计时器 
+        public void Start()
+        {
+            // 来让等待线程工作 
+            Thread.Sleep(0);
+            QueryPerformanceCounter(out _startTime);
+        }
+
+        // 开始计时器 
+        public static HiPerfTimer StartNew()
+        {
+            HiPerfTimer timer = new HiPerfTimer();
+            timer.Start();
+            return timer;
+        }
+
+        // 停止计时器 
+        public void Stop()
+        {
+            QueryPerformanceCounter(out _stopTime);
+        }
+
+        // 返回计时器经过时间(单位:秒) 
+        public double Duration => (_stopTime - _startTime) / (double)_freq;
+
+        /// <summary>
+        /// 执行一个方法并测试执行时间
+        /// </summary>
+        /// <param name="action"></param>
+        /// <returns></returns>
+        public static double Execute(Action action)
+        {
+            var timer = new HiPerfTimer();
+            timer.Start();
+            action();
+            timer.Stop();
+            return timer.Duration;
+        }
+    }
+}

+ 11 - 0
Masuit.Tools/Systems/LimitedQueue.cs

@@ -8,13 +8,24 @@ namespace Masuit.Tools.Systems
     /// <typeparam name="T"></typeparam>
     public class LimitedQueue<T> : Queue<T>
     {
+        /// <summary>
+        /// 队列长度
+        /// </summary>
         public int Limit { get; set; }
 
+        /// <summary>
+        /// 定长队列
+        /// </summary>
+        /// <param name="limit"></param>
         public LimitedQueue(int limit) : base(limit)
         {
             Limit = limit;
         }
 
+        /// <summary>
+        /// 入队
+        /// </summary>
+        /// <param name="item"></param>
         public new void Enqueue(T item)
         {
             if (Count >= Limit)

+ 20 - 2
Masuit.Tools/Systems/Lock.cs

@@ -1,10 +1,19 @@
-using System;
-using StackExchange.Redis;
+using StackExchange.Redis;
+using System;
 
 namespace Masuit.Tools.Systems
 {
+    /// <summary>
+    /// 分布式锁
+    /// </summary>
     public class Lock
     {
+        /// <summary>
+        /// 分布式锁
+        /// </summary>
+        /// <param name="resource"></param>
+        /// <param name="val"></param>
+        /// <param name="validity"></param>
         public Lock(RedisKey resource, RedisValue val, TimeSpan validity)
         {
             Resource = resource;
@@ -12,10 +21,19 @@ namespace Masuit.Tools.Systems
             Validity = validity;
         }
 
+        /// <summary>
+        /// 
+        /// </summary>
         public RedisKey Resource { get; }
 
+        /// <summary>
+        /// 
+        /// </summary>
         public RedisValue Value { get; }
 
+        /// <summary>
+        /// 
+        /// </summary>
         public TimeSpan Validity { get; }
     }
 }

+ 28 - 3
Masuit.Tools/Systems/RedisLock.cs

@@ -1,18 +1,24 @@
-using System;
+using StackExchange.Redis;
+using System;
 using System.Collections.Concurrent;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Timers;
-using StackExchange.Redis;
 
 namespace Masuit.Tools.Systems
 {
+    /// <summary>
+    /// Redis分布式锁
+    /// </summary>
     public class RedisLock : IDisposable
     {
         #region Property
 
         private bool _isDisposed;
 
+        /// <summary>
+        /// 终结器
+        /// </summary>
         ~RedisLock()
         {
             Dispose(false);
@@ -245,13 +251,21 @@ namespace Masuit.Tools.Systems
             return task;
         }
 
+        /// <summary>
+        /// 创建唯一锁id
+        /// </summary>
+        /// <returns></returns>
         protected static string CreateUniqueLockId()
         {
             return string.Concat(Guid.NewGuid().ToString(), Thread.CurrentThread.ManagedThreadId);
         }
 
+        /// <summary>
+        /// 设置超时
+        /// </summary>
+        /// <param name="doWork"></param>
+        /// <param name="time"></param>
         protected void SetTimeOut(ElapsedEventHandler doWork, int time)
-
         {
             System.Timers.Timer timer = new System.Timers.Timer();
             timer.Interval = time;
@@ -260,6 +274,13 @@ namespace Masuit.Tools.Systems
             timer.Start();
         }
 
+        /// <summary>
+        /// 任务超时
+        /// </summary>
+        /// <param name="action"></param>
+        /// <param name="lockObj"></param>
+        /// <param name="time"></param>
+        /// <returns></returns>
         protected CancellationTokenSource TaskTimeOut(Func<Lock, bool> action, Lock lockObj, int time)
         {
             var timeoutCancellationTokenSource = new CancellationTokenSource();
@@ -310,6 +331,10 @@ namespace Masuit.Tools.Systems
             GC.SuppressFinalize(this);
         }
 
+        /// <summary>
+        /// 释放锁
+        /// </summary>
+        /// <param name="disposing"></param>
         public virtual void Dispose(bool disposing)
         {
             if (_isDisposed)

+ 2 - 2
Masuit.Tools/Validator/ComplexPassword.cs

@@ -1,7 +1,7 @@
 using System.ComponentModel.DataAnnotations;
 using System.Text.RegularExpressions;
 
-namespace Masuit.Tools.Validator
+namespace Masuit.Tools.Core.Validator
 {
     /// <summary>
     /// 强密码验证
@@ -9,7 +9,7 @@ namespace Masuit.Tools.Validator
     public class ComplexPassword : ValidationAttribute
     {
         /// <summary>
-        /// 密码复杂度校验
+        /// 校验密码强度
         /// </summary>
         /// <param name="value"></param>
         /// <returns></returns>

+ 3 - 3
Masuit.Tools/Validator/IsEmailAttribute.cs

@@ -1,14 +1,14 @@
 using System.ComponentModel.DataAnnotations;
 
-namespace Masuit.Tools.Validator
+namespace Masuit.Tools.Core.Validator
 {
     /// <summary>
-    /// Email校验器
+    /// 邮箱校验
     /// </summary>
     public class IsEmailAttribute : ValidationAttribute
     {
         /// <summary>
-        /// Email校验
+        /// 邮箱校验
         /// </summary>
         /// <param name="value"></param>
         /// <returns></returns>

+ 4 - 4
Masuit.Tools/Validator/IsIPAddressAttribute.cs

@@ -1,6 +1,6 @@
 using System.ComponentModel.DataAnnotations;
 
-namespace Masuit.Tools.Validator
+namespace Masuit.Tools.Core.Validator
 {
     /// <summary>
     /// 验证IPv4地址是否合法
@@ -8,7 +8,7 @@ namespace Masuit.Tools.Validator
     public class IsIPAddressAttribute : ValidationAttribute
     {
         /// <summary>
-        /// IPv4校验
+        /// 验证IPv4地址是否合法
         /// </summary>
         /// <param name="value"></param>
         /// <returns></returns>
@@ -19,8 +19,8 @@ namespace Masuit.Tools.Validator
                 ErrorMessage = "IP地址不能为空!";
                 return false;
             }
-            string ip = value as string;
-            if (ip.MatchInetAddress())
+            string email = value as string;
+            if (email.MatchInetAddress())
             {
                 return true;
             }

+ 2 - 2
Masuit.Tools/Validator/IsPhoneAttribute.cs

@@ -1,6 +1,6 @@
 using System.ComponentModel.DataAnnotations;
 
-namespace Masuit.Tools.Validator
+namespace Masuit.Tools.Core.Validator
 {
     /// <summary>
     /// 验证手机号码是否合法
@@ -8,7 +8,7 @@ namespace Masuit.Tools.Validator
     public class IsPhoneAttribute : ValidationAttribute
     {
         /// <summary>
-        /// 大陆手机号校验
+        /// 验证手机号码是否合法
         /// </summary>
         /// <param name="value"></param>
         /// <returns></returns>

+ 13 - 1
Masuit.Tools/Validator/MaxValueAttribute.cs

@@ -1,7 +1,7 @@
 using System;
 using System.ComponentModel.DataAnnotations;
 
-namespace Masuit.Tools.Validator
+namespace Masuit.Tools.Core.Validator
 {
     /// <summary>
     /// 最大值校验
@@ -9,16 +9,28 @@ namespace Masuit.Tools.Validator
     public class MaxValueAttribute : ValidationAttribute
     {
         private double MaxValue { get; }
+
+        /// <summary>
+        /// 最大值
+        /// </summary>
+        /// <param name="value"></param>
         public MaxValueAttribute(double value)
         {
             MaxValue = value;
         }
+
+        /// <summary>
+        /// 最大值校验
+        /// </summary>
+        /// <param name="value"></param>
+        /// <returns></returns>
         public override bool IsValid(object value)
         {
             if (value is null)
             {
                 return true;
             }
+
             var input = Convert.ToDouble(value);
             return input <= MaxValue;
         }

+ 16 - 1
Masuit.Tools/Validator/MinValueAttribute.cs

@@ -1,21 +1,36 @@
 using System;
 using System.ComponentModel.DataAnnotations;
 
-namespace Masuit.Tools.Validator
+namespace Masuit.Tools.Core.Validator
 {
+    /// <summary>
+    /// 最小值校验
+    /// </summary>
     public class MinValueAttribute : ValidationAttribute
     {
         private double MinValue { get; set; }
+
+        /// <summary>
+        /// 最小值
+        /// </summary>
+        /// <param name="value"></param>
         public MinValueAttribute(double value)
         {
             MinValue = value;
         }
+
+        /// <summary>
+        /// 最小值校验
+        /// </summary>
+        /// <param name="value"></param>
+        /// <returns></returns>
         public override bool IsValid(object value)
         {
             if (value is null)
             {
                 return true;
             }
+
             var input = Convert.ToDouble(value);
             return input > MinValue;
         }

+ 16 - 160
Test/Program.cs

@@ -1,172 +1,28 @@
-using System;
+using Masuit.Tools.Strings;
+using Masuit.Tools.Systems;
+using System;
 using System.Collections.Generic;
-using System.Linq;
+using System.Diagnostics;
 
 namespace Test
 {
-    /// <summary>
-    /// 路由计算引擎
-    /// </summary>
-    /// <typeparam name="T"></typeparam>
-    public class RouteEngine<T>
-    {
-        /// <summary>
-        /// 节点信息
-        /// </summary>
-        private List<Node<T>> Nodes { get; set; }
-
-        /// <summary>
-        /// 路由结果
-        /// </summary>
-        private Dictionary<string, int> RouteList { get; set; } = new Dictionary<string, int>();
-
-        public RouteEngine(List<Node<T>> nodes)
-        {
-            Nodes = nodes;
-        }
-
-        /// <summary>
-        /// 递归将每条路都计算出来
-        /// </summary>
-        /// <param name="node"></param>
-        /// <param name="route"></param>
-        /// <param name="dis"></param>
-        private void InterateRoute(Node<T> node, string route, int dis)
-        {
-            if (node.Prevs.Any())
-            {
-                foreach (var prev in node.Prevs)
-                {
-                    RouteList[prev.Key.Name + "," + route] = dis + prev.Value;
-                    InterateRoute(prev.Key, prev.Key.Name + "," + route, dis + prev.Value);
-                }
-            }
-        }
-
-        /// <summary>
-        /// 获得路径
-        /// </summary>
-        /// <param name="start"></param>
-        /// <param name="end"></param>
-        /// <param name="shortest"></param>
-        /// <returns></returns>
-        public (List<Route<T>>, HashSet<Node<T>>) GetRoutes(Node<T> start, Node<T> end, bool shortest)
-        {
-            InterateRoute(end, end.Name, 0);
-            var list = new List<Route<T>>();
-            var nodes = new HashSet<Node<T>>();
-            var routes = RouteList.Where(k => k.Key.StartsWith(start.Name) && k.Key.EndsWith(end.Name));
-            var route = (shortest ? routes.OrderBy(x => x.Value) : routes.OrderByDescending(x => x.Value)).FirstOrDefault().Key;
-            string[] strs = route.Split(',');
-            for (var i = 0; i < strs.Length - 1; i++)
-            {
-                Node<T> src = Nodes.Find(n => n.Name.Equals(strs[i]));
-                Node<T> dest = Nodes.Find(n => n.Name.Equals(strs[i + 1]));
-                list.Add(new Route<T>(src, dest, dest.Prevs[src]));
-                nodes.Add(src);
-                nodes.Add(dest);
-            }
-            return (list, nodes);
-        }
-    }
-
-    /// <summary>
-    /// 路由
-    /// </summary>
-    /// <typeparam name="T"></typeparam>
-    public class Route<T>
-    {
-        public Route(Node<T> src, Node<T> dest, int distance)
-        {
-            Source = src;
-            Dest = dest;
-            Distance = distance;
-        }
-
-        /// <summary>
-        /// 开始节点
-        /// </summary>
-        public Node<T> Source { get; set; }
-
-        /// <summary>
-        /// 结束节点
-        /// </summary>
-        public Node<T> Dest { get; set; }
-
-        /// <summary>
-        /// 距离
-        /// </summary>
-        public int Distance { get; set; }
-    }
-
-    /// <summary>
-    /// 节点
-    /// </summary>
-    /// <typeparam name="T"></typeparam>
-    public class Node<T>
-    {
-        public Node(string name)
-        {
-            Name = name;
-            Prevs = new Dictionary<Node<T>, int>();
-        }
-
-        /// <summary>
-        /// 节点名
-        /// </summary>
-        public string Name { get; set; }
-
-        /// <summary>
-        /// 前面的节点以及到前一个节点需要的距离
-        /// </summary>
-        public Dictionary<Node<T>, int> Prevs { get; set; }
-    }
-
     class Program
     {
         static void Main(string[] args)
         {
-            Node<string> a = new Node<string>("A");
-            Node<string> b = new Node<string>("B");
-            Node<string> c = new Node<string>("C");
-            Node<string> d = new Node<string>("D");
-            Node<string> e = new Node<string>("E");
-            SetRoutePath(a, b, 1);
-            SetRoutePath(b, c, 2);
-            SetRoutePath(a, c, 2);
-            SetRoutePath(b, d, 3);
-            SetRoutePath(c, d, 5);
-            SetRoutePath(b, e, 9);
-            SetRoutePath(d, e, 4);
-            List<Node<string>> nodes = new List<Node<string>>()
+            var timer = HiPerfTimer.Execute(() =>
             {
-                a,
-                b,
-                c,
-                d,
-                e
-            };
-            var engine = new RouteEngine<string>(nodes);
-            var (routes, routeNodes) = engine.GetRoutes(a, e, false);
-            foreach (var x in routes)
-            {
-                Console.WriteLine(x.Source.Name + "->" + x.Dest.Name + ":" + x.Distance);
-            }
-
-            Console.WriteLine("最长路径:" + string.Join("->", routeNodes.Select(x => x.Name)) + ":" + routes.Sum(r => r.Distance));
-
-            (routes, routeNodes) = engine.GetRoutes(a, e, true);
-            foreach (var x in routes)
-            {
-                Console.WriteLine(x.Source.Name + "->" + x.Dest.Name + ":" + x.Distance);
-            }
-
-            Console.WriteLine("最短路径:" + string.Join("->", routeNodes.Select(x => x.Name)) + ":" + routes.Sum(r => r.Distance));
-        }
-
-        private static void SetRoutePath(Node<string> start, Node<string> end, int distance)
-        {
-            end.Prevs.Add(start, distance);
+                NumberFormater nf = new NumberFormater(36);
+                var set = new HashSet<string>();
+                for (int i = 0; i < 1000000; i++)
+                {
+                    string ts = nf.ToString(Stopwatch.GetTimestamp());
+                    //Console.WriteLine(ts);
+                    set.Add(ts);
+                }
+                Console.WriteLine(set.Count);
+            });
+            Console.WriteLine(timer);
         }
     }
 }

+ 2 - 2
Test/Test.csproj

@@ -48,8 +48,8 @@
     <Reference Include="MongoDB.Driver.Core, Version=2.7.2.0, Culture=neutral, processorArchitecture=MSIL">
       <HintPath>..\packages\MongoDB.Driver.Core.2.7.2\lib\net45\MongoDB.Driver.Core.dll</HintPath>
     </Reference>
-    <Reference Include="Newtonsoft.Json, Version=11.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
-      <HintPath>..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
+    <Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
+      <HintPath>..\packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
     </Reference>
     <Reference Include="StackExchange.Redis, Version=1.2.6.0, Culture=neutral, processorArchitecture=MSIL">
       <HintPath>..\packages\StackExchange.Redis.1.2.6\lib\net45\StackExchange.Redis.dll</HintPath>

+ 1 - 1
Test/packages.config

@@ -4,7 +4,7 @@
   <package id="MongoDB.Bson" version="2.7.2" targetFramework="net45" />
   <package id="MongoDB.Driver" version="2.7.2" targetFramework="net45" />
   <package id="MongoDB.Driver.Core" version="2.7.2" targetFramework="net45" />
-  <package id="Newtonsoft.Json" version="11.0.2" targetFramework="net45" />
+  <package id="Newtonsoft.Json" version="12.0.1" targetFramework="net45" />
   <package id="StackExchange.Redis" version="1.2.6" targetFramework="net45" />
   <package id="System.Buffers" version="4.4.0" targetFramework="net45" />
   <package id="System.Runtime.InteropServices.RuntimeInformation" version="4.3.0" targetFramework="net45" />