| 
									
										
										
										
											2021-03-29 23:35:02 +08:00
										 |  |  |  | /* | 
					
						
							|  |  |  |  |  * 版权属于:yitter(yitter@126.com) | 
					
						
							|  |  |  |  |  * 开源地址:https://gitee.com/yitter/idgenerator | 
					
						
							|  |  |  |  |  * 版权协议:MIT | 
					
						
							|  |  |  |  |  * 版权说明:只要保留本版权,你可以免费使用、修改、分发本代码。 | 
					
						
							|  |  |  |  |  * 免责条款:任何因为本代码产生的系统、法律、政治、宗教问题,均与版权所有者无关。 | 
					
						
							|  |  |  |  |  *  | 
					
						
							|  |  |  |  |  */ | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | using System; | 
					
						
							| 
									
										
										
										
											2021-03-13 16:21:56 +08:00
										 |  |  |  | using System.Threading; | 
					
						
							|  |  |  |  | using System.Threading.Tasks; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | namespace Yitter.IdGenerator | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     /// <summary> | 
					
						
							|  |  |  |  |     /// 雪花漂移算法 | 
					
						
							|  |  |  |  |     /// </summary>  | 
					
						
							|  |  |  |  |     internal class SnowWorkerM1 : ISnowWorker | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         /// <summary> | 
					
						
							|  |  |  |  |         /// 基础时间 | 
					
						
							|  |  |  |  |         /// </summary> | 
					
						
							| 
									
										
										
										
											2021-03-29 23:35:02 +08:00
										 |  |  |  |         protected readonly DateTime BaseTime; | 
					
						
							| 
									
										
										
										
											2021-03-13 16:21:56 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |         /// <summary> | 
					
						
							|  |  |  |  |         /// 机器码 | 
					
						
							|  |  |  |  |         /// </summary> | 
					
						
							|  |  |  |  |         protected readonly ushort WorkerId = 0; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         /// <summary> | 
					
						
							|  |  |  |  |         /// 机器码位长 | 
					
						
							|  |  |  |  |         /// </summary> | 
					
						
							|  |  |  |  |         protected readonly byte WorkerIdBitLength = 0; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         /// <summary> | 
					
						
							|  |  |  |  |         /// 自增序列数位长 | 
					
						
							|  |  |  |  |         /// </summary> | 
					
						
							|  |  |  |  |         protected readonly byte SeqBitLength = 0; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         /// <summary> | 
					
						
							| 
									
										
										
										
											2021-03-29 23:35:02 +08:00
										 |  |  |  |         /// 最大序列数(含) | 
					
						
							| 
									
										
										
										
											2021-03-13 16:21:56 +08:00
										 |  |  |  |         /// </summary> | 
					
						
							|  |  |  |  |         protected readonly int MaxSeqNumber = 0; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         /// <summary> | 
					
						
							| 
									
										
										
										
											2021-03-29 23:35:02 +08:00
										 |  |  |  |         /// 最小序列数(含) | 
					
						
							| 
									
										
										
										
											2021-03-13 16:21:56 +08:00
										 |  |  |  |         /// </summary> | 
					
						
							|  |  |  |  |         protected readonly ushort MinSeqNumber = 0; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         /// <summary> | 
					
						
							|  |  |  |  |         /// 最大漂移次数 | 
					
						
							|  |  |  |  |         /// </summary> | 
					
						
							|  |  |  |  |         protected readonly int TopOverCostCount = 0; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         protected readonly byte _TimestampShift = 0; | 
					
						
							|  |  |  |  |         protected static object _SyncLock = new object(); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         protected ushort _CurrentSeqNumber; | 
					
						
							|  |  |  |  |         protected long _LastTimeTick = -1L; | 
					
						
							|  |  |  |  |         protected long _TurnBackTimeTick = -1L; | 
					
						
							| 
									
										
										
										
											2021-03-29 23:35:02 +08:00
										 |  |  |  |         protected byte _TurnBackIndex = 0; | 
					
						
							| 
									
										
										
										
											2021-03-13 16:21:56 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |         protected bool _IsOverCost = false; | 
					
						
							|  |  |  |  |         protected int _OverCostCountInOneTerm = 0; | 
					
						
							|  |  |  |  |         protected int _GenCountInOneTerm = 0; | 
					
						
							|  |  |  |  |         protected int _TermIndex = 0; | 
					
						
							| 
									
										
										
										
											2021-03-29 23:35:02 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |         //private static long _StartTimeTick = 0; | 
					
						
							|  |  |  |  |         //private static long _BaseTimeTick = 0; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-13 16:21:56 +08:00
										 |  |  |  |         public Action<OverCostActionArg> GenAction { get; set; } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-29 23:35:02 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-13 16:21:56 +08:00
										 |  |  |  |         public SnowWorkerM1(IdGeneratorOptions options) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             WorkerId = options.WorkerId; | 
					
						
							|  |  |  |  |             WorkerIdBitLength = options.WorkerIdBitLength; | 
					
						
							|  |  |  |  |             SeqBitLength = options.SeqBitLength; | 
					
						
							|  |  |  |  |             MaxSeqNumber = options.MaxSeqNumber; | 
					
						
							|  |  |  |  |             MinSeqNumber = options.MinSeqNumber; | 
					
						
							|  |  |  |  |             TopOverCostCount = options.TopOverCostCount; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-29 23:35:02 +08:00
										 |  |  |  |             if (options.BaseTime != DateTime.MinValue) | 
					
						
							| 
									
										
										
										
											2021-03-13 16:21:56 +08:00
										 |  |  |  |             { | 
					
						
							| 
									
										
										
										
											2021-03-29 23:35:02 +08:00
										 |  |  |  |                 BaseTime = options.BaseTime; | 
					
						
							| 
									
										
										
										
											2021-03-13 16:21:56 +08:00
										 |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             if (WorkerId < 1) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 WorkerId = (ushort)DateTime.Now.Millisecond; | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             if (SeqBitLength == 0) | 
					
						
							|  |  |  |  |             { | 
					
						
							| 
									
										
										
										
											2021-03-29 23:35:02 +08:00
										 |  |  |  |                 SeqBitLength = 6; | 
					
						
							| 
									
										
										
										
											2021-03-13 16:21:56 +08:00
										 |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             if (WorkerIdBitLength == 0) | 
					
						
							|  |  |  |  |             { | 
					
						
							| 
									
										
										
										
											2021-03-29 23:35:02 +08:00
										 |  |  |  |                 WorkerIdBitLength = 6; | 
					
						
							| 
									
										
										
										
											2021-03-13 16:21:56 +08:00
										 |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             if (MaxSeqNumber == 0) | 
					
						
							|  |  |  |  |             { | 
					
						
							| 
									
										
										
										
											2021-03-29 23:35:02 +08:00
										 |  |  |  |                 MaxSeqNumber = (1 << SeqBitLength) - 1; | 
					
						
							| 
									
										
										
										
											2021-03-13 16:21:56 +08:00
										 |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             _TimestampShift = (byte)(WorkerIdBitLength + SeqBitLength); | 
					
						
							| 
									
										
										
										
											2021-03-29 23:35:02 +08:00
										 |  |  |  |             _CurrentSeqNumber = options.MinSeqNumber; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             //_BaseTimeTick = BaseTime.Ticks; | 
					
						
							|  |  |  |  |             //_StartTimeTick = (long)(DateTime.UtcNow.Subtract(BaseTime).TotalMilliseconds) - Environment.TickCount; | 
					
						
							| 
									
										
										
										
											2021-03-13 16:21:56 +08:00
										 |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         private void DoGenIdAction(OverCostActionArg arg) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             Task.Run(() => | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 GenAction(arg); | 
					
						
							|  |  |  |  |             }); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-29 23:35:02 +08:00
										 |  |  |  |         private void BeginOverCostAction(in long useTimeTick) | 
					
						
							| 
									
										
										
										
											2021-03-13 16:21:56 +08:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2021-03-29 23:35:02 +08:00
										 |  |  |  |             return; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-13 16:21:56 +08:00
										 |  |  |  |             if (GenAction == null) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 return; | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             DoGenIdAction(new OverCostActionArg( | 
					
						
							|  |  |  |  |                 WorkerId, | 
					
						
							|  |  |  |  |                 useTimeTick, | 
					
						
							|  |  |  |  |                 1, | 
					
						
							|  |  |  |  |                 _OverCostCountInOneTerm, | 
					
						
							|  |  |  |  |                 _GenCountInOneTerm, | 
					
						
							|  |  |  |  |                 _TermIndex)); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-29 23:35:02 +08:00
										 |  |  |  |         private void EndOverCostAction(in long useTimeTick) | 
					
						
							| 
									
										
										
										
											2021-03-13 16:21:56 +08:00
										 |  |  |  |         { | 
					
						
							|  |  |  |  |             if (_TermIndex > 10000) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 _TermIndex = 0; | 
					
						
							|  |  |  |  |             } | 
					
						
							| 
									
										
										
										
											2021-03-29 23:35:02 +08:00
										 |  |  |  |             return; | 
					
						
							| 
									
										
										
										
											2021-03-13 16:21:56 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |             if (GenAction == null) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 return; | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             DoGenIdAction(new OverCostActionArg( | 
					
						
							|  |  |  |  |                 WorkerId, | 
					
						
							|  |  |  |  |                 useTimeTick, | 
					
						
							|  |  |  |  |                 2, | 
					
						
							|  |  |  |  |                 _OverCostCountInOneTerm, | 
					
						
							|  |  |  |  |                 _GenCountInOneTerm, | 
					
						
							|  |  |  |  |                 _TermIndex)); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-29 23:35:02 +08:00
										 |  |  |  |         private void BeginTurnBackAction(in long useTimeTick) | 
					
						
							| 
									
										
										
										
											2021-03-13 16:21:56 +08:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2021-03-29 23:35:02 +08:00
										 |  |  |  |             return; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-13 16:21:56 +08:00
										 |  |  |  |             if (GenAction == null) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 return; | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             DoGenIdAction(new OverCostActionArg( | 
					
						
							|  |  |  |  |             WorkerId, | 
					
						
							|  |  |  |  |             useTimeTick, | 
					
						
							|  |  |  |  |             8, | 
					
						
							| 
									
										
										
										
											2021-03-29 23:35:02 +08:00
										 |  |  |  |             0, | 
					
						
							|  |  |  |  |             0, | 
					
						
							|  |  |  |  |             _TurnBackIndex)); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         private void EndTurnBackAction(in long useTimeTick) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             return; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             if (GenAction == null) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 return; | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             DoGenIdAction(new OverCostActionArg( | 
					
						
							|  |  |  |  |             WorkerId, | 
					
						
							|  |  |  |  |             useTimeTick, | 
					
						
							|  |  |  |  |             9, | 
					
						
							|  |  |  |  |             0, | 
					
						
							|  |  |  |  |             0, | 
					
						
							|  |  |  |  |             _TurnBackIndex)); | 
					
						
							| 
									
										
										
										
											2021-03-13 16:21:56 +08:00
										 |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         private long NextOverCostId() | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             long currentTimeTick = GetCurrentTimeTick(); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             if (currentTimeTick > _LastTimeTick) | 
					
						
							|  |  |  |  |             { | 
					
						
							| 
									
										
										
										
											2021-03-29 23:35:02 +08:00
										 |  |  |  |                 EndOverCostAction(currentTimeTick); | 
					
						
							| 
									
										
										
										
											2021-03-13 16:21:56 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |                 _LastTimeTick = currentTimeTick; | 
					
						
							|  |  |  |  |                 _CurrentSeqNumber = MinSeqNumber; | 
					
						
							|  |  |  |  |                 _IsOverCost = false; | 
					
						
							|  |  |  |  |                 _OverCostCountInOneTerm = 0; | 
					
						
							|  |  |  |  |                 _GenCountInOneTerm = 0; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                 return CalcId(_LastTimeTick); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             if (_OverCostCountInOneTerm >= TopOverCostCount) | 
					
						
							|  |  |  |  |             { | 
					
						
							| 
									
										
										
										
											2021-03-29 23:35:02 +08:00
										 |  |  |  |                 EndOverCostAction(currentTimeTick); | 
					
						
							| 
									
										
										
										
											2021-03-13 16:21:56 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |                 _LastTimeTick = GetNextTimeTick(); | 
					
						
							|  |  |  |  |                 _CurrentSeqNumber = MinSeqNumber; | 
					
						
							|  |  |  |  |                 _IsOverCost = false; | 
					
						
							|  |  |  |  |                 _OverCostCountInOneTerm = 0; | 
					
						
							|  |  |  |  |                 _GenCountInOneTerm = 0; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                 return CalcId(_LastTimeTick); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             if (_CurrentSeqNumber > MaxSeqNumber) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 _LastTimeTick++; | 
					
						
							|  |  |  |  |                 _CurrentSeqNumber = MinSeqNumber; | 
					
						
							|  |  |  |  |                 _IsOverCost = true; | 
					
						
							|  |  |  |  |                 _OverCostCountInOneTerm++; | 
					
						
							|  |  |  |  |                 _GenCountInOneTerm++; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                 return CalcId(_LastTimeTick); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             _GenCountInOneTerm++; | 
					
						
							|  |  |  |  |             return CalcId(_LastTimeTick); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         private long NextNormalId() | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             long currentTimeTick = GetCurrentTimeTick(); | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-29 23:35:02 +08:00
										 |  |  |  |             if (currentTimeTick < _LastTimeTick) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 if (_TurnBackTimeTick < 1) | 
					
						
							|  |  |  |  |                 { | 
					
						
							|  |  |  |  |                     _TurnBackTimeTick = _LastTimeTick - 1; | 
					
						
							|  |  |  |  |                     _TurnBackIndex++; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                     // 每毫秒序列数的前5位是预留位,0用于手工新值,1-4是时间回拨次序 | 
					
						
							|  |  |  |  |                     // 最多4次回拨(防止回拨重叠) | 
					
						
							|  |  |  |  |                     if (_TurnBackIndex > 4) | 
					
						
							|  |  |  |  |                     { | 
					
						
							|  |  |  |  |                         _TurnBackIndex = 1; | 
					
						
							|  |  |  |  |                     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                     BeginTurnBackAction(_TurnBackTimeTick); | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                 Thread.Sleep(10); | 
					
						
							|  |  |  |  |                 return CalcTurnBackId(_TurnBackTimeTick); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             // 时间追平时,_TurnBackTimeTick清零 | 
					
						
							|  |  |  |  |             if (_TurnBackTimeTick > 0) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 EndTurnBackAction(_TurnBackTimeTick); | 
					
						
							|  |  |  |  |                 _TurnBackTimeTick = 0; | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-13 16:21:56 +08:00
										 |  |  |  |             if (currentTimeTick > _LastTimeTick) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 _LastTimeTick = currentTimeTick; | 
					
						
							|  |  |  |  |                 _CurrentSeqNumber = MinSeqNumber; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                 return CalcId(_LastTimeTick); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             if (_CurrentSeqNumber > MaxSeqNumber) | 
					
						
							|  |  |  |  |             { | 
					
						
							| 
									
										
										
										
											2021-03-29 23:35:02 +08:00
										 |  |  |  |                 BeginOverCostAction(currentTimeTick); | 
					
						
							| 
									
										
										
										
											2021-03-13 16:21:56 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |                 _TermIndex++; | 
					
						
							|  |  |  |  |                 _LastTimeTick++; | 
					
						
							|  |  |  |  |                 _CurrentSeqNumber = MinSeqNumber; | 
					
						
							|  |  |  |  |                 _IsOverCost = true; | 
					
						
							| 
									
										
										
										
											2021-03-29 23:35:02 +08:00
										 |  |  |  |                 _OverCostCountInOneTerm = 1; | 
					
						
							| 
									
										
										
										
											2021-03-13 16:21:56 +08:00
										 |  |  |  |                 _GenCountInOneTerm = 1; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                 return CalcId(_LastTimeTick); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             return CalcId(_LastTimeTick); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         private long CalcId(in long useTimeTick) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             var result = ((useTimeTick << _TimestampShift) + | 
					
						
							|  |  |  |  |                 ((long)WorkerId << SeqBitLength) + | 
					
						
							|  |  |  |  |                 (uint)_CurrentSeqNumber); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             _CurrentSeqNumber++; | 
					
						
							|  |  |  |  |             return result; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         private long CalcTurnBackId(in long useTimeTick) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             var result = ((useTimeTick << _TimestampShift) + | 
					
						
							| 
									
										
										
										
											2021-03-29 23:35:02 +08:00
										 |  |  |  |                 ((long)WorkerId << SeqBitLength) + _TurnBackIndex); | 
					
						
							| 
									
										
										
										
											2021-03-13 16:21:56 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |             _TurnBackTimeTick--; | 
					
						
							|  |  |  |  |             return result; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         protected virtual long GetCurrentTimeTick() | 
					
						
							|  |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2021-03-29 23:35:02 +08:00
										 |  |  |  |             //return (long)(DateTime.UtcNow - BaseTime).Ticks; | 
					
						
							|  |  |  |  |             //return (long)(_StartTimeTick + Environment.TickCount); | 
					
						
							|  |  |  |  |             return (long)(DateTime.UtcNow - BaseTime).TotalMilliseconds; | 
					
						
							| 
									
										
										
										
											2021-03-13 16:21:56 +08:00
										 |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         protected virtual long GetNextTimeTick() | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             long tempTimeTicker = GetCurrentTimeTick(); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             while (tempTimeTicker <= _LastTimeTick) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 tempTimeTicker = GetCurrentTimeTick(); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             return tempTimeTicker; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         public virtual long NextId() | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             lock (_SyncLock) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 return _IsOverCost ? NextOverCostId() : NextNormalId(); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | } |