SoftNumerical.cs
9.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
using HslCommunication.Core;
using System;
using System.Text;
using System.Threading;
namespace HslCommunication.BasicFramework
{
/********************************************************************************************
*
* 一个高度灵活的流水号生成的类,允许根据指定规则加上时间数据进行生成
*
* 根据保存机制进行优化,必须做到好并发量
*
********************************************************************************************/
/// <summary>
/// 一个用于自动流水号生成的类,必须指定保存的文件,实时保存来确认安全
/// </summary>
/// <remarks>
/// <note type="important">
/// 序号生成器软件,当获取序列号,清空序列号操作后,会自动的将ID号存储到本地的文件中,存储方式采用乐观并发模型实现。
/// </note>
/// </remarks>
/// <example>
/// 此处举个例子,也是Demo程序的源代码,包含了2个按钮的示例和瞬间调用100万次的性能示例。
/// <note type="tip">百万次调用的实际耗时取决于计算机的性能,不同的计算机的表现存在差异,比如作者的:i5-4590cpu,内存ddr3-8G表示差不多在800毫秒左右</note>
/// <code lang="cs" source="TestProject\HslCommunicationDemo\FormSeqCreate.cs" region="FormSeqCreate" title="示例代码" />
/// </example>
public sealed class SoftNumericalOrder : SoftFileSaveBase
{
#region Constructor
/// <summary>
/// 实例化一个流水号生成的对象
/// </summary>
/// <param name="textHead">流水号的头文本</param>
/// <param name="timeFormate">流水号带的时间信息</param>
/// <param name="numberLength">流水号数字的标准长度,不够补0</param>
/// <param name="fileSavePath">流水号存储的文本位置</param>
public SoftNumericalOrder(string textHead, string timeFormate, int numberLength, string fileSavePath)
{
LogHeaderText = "SoftNumericalOrder";
TextHead = textHead;
TimeFormate = timeFormate;
NumberLength = numberLength;
FileSavePath = fileSavePath;
LoadByFile();
AsyncCoordinator = new HslAsyncCoordinator(() =>
{
if (!string.IsNullOrEmpty(FileSavePath))
{
using (System.IO.StreamWriter sw = new System.IO.StreamWriter(FileSavePath, false, Encoding.Default))
{
sw.Write(CurrentIndex);
}
}
});
}
#endregion
#region Private Member
/// <summary>
/// 当前的生成序列号
/// </summary>
private long CurrentIndex = 0;
/// <summary>
/// 流水号的文本头
/// </summary>
private string TextHead = string.Empty;
/// <summary>
/// 时间格式默认年月日
/// </summary>
private string TimeFormate = "yyyyMMdd";
/// <summary>
/// 流水号数字应该显示的长度
/// </summary>
private int NumberLength = 5;
#endregion
#region Public Method
/// <summary>
/// 获取流水号的值
/// </summary>
/// <returns>字符串信息</returns>
public override string ToSaveString()
{
return CurrentIndex.ToString();
}
/// <summary>
/// 加载流水号
/// </summary>
/// <param name="content">源字符串信息</param>
public override void LoadByString(string content)
{
CurrentIndex = Convert.ToInt64(content);
}
/// <summary>
/// 清除流水号计数,进行重新计数
/// </summary>
public void ClearNumericalOrder()
{
Interlocked.Exchange(ref CurrentIndex, 0);
AsyncCoordinator.StartOperaterInfomation();
}
/// <summary>
/// 获取流水号数据
/// </summary>
/// <returns>新增计数后的信息</returns>
public string GetNumericalOrder()
{
long number = Interlocked.Increment(ref CurrentIndex);
AsyncCoordinator.StartOperaterInfomation();
if (string.IsNullOrEmpty(TimeFormate))
{
return TextHead + number.ToString().PadLeft(NumberLength, '0');
}
else
{
return TextHead + DateTime.Now.ToString(TimeFormate) + number.ToString().PadLeft(NumberLength, '0');
}
}
/// <summary>
/// 获取流水号数据
/// </summary>
/// <param name="textHead">指定一个新的文本头</param>
/// <returns>带头信息的计数后的信息</returns>
public string GetNumericalOrder(string textHead)
{
long number = Interlocked.Increment(ref CurrentIndex);
AsyncCoordinator.StartOperaterInfomation();
if (string.IsNullOrEmpty(TimeFormate))
{
return textHead + number.ToString().PadLeft(NumberLength, '0');
}
else
{
return textHead + DateTime.Now.ToString(TimeFormate) + number.ToString().PadLeft(NumberLength, '0');
}
}
/// <summary>
/// 单纯的获取数字形式的流水号
/// </summary>
/// <returns>新增计数后的信息</returns>
public long GetLongOrder()
{
long number = Interlocked.Increment(ref CurrentIndex);
AsyncCoordinator.StartOperaterInfomation();
return number;
}
#endregion
#region High Performance Save
/// <summary>
/// 高性能存储块
/// </summary>
private HslAsyncCoordinator AsyncCoordinator = null;
#endregion
}
/// <summary>
/// 一个简单的不持久化的序号自增类,采用线程安全实现,并允许指定最大数字,将包含该最大值,到达后清空从指定数开始
/// </summary>
public sealed class SoftIncrementCount : IDisposable
{
#region Constructor
/// <summary>
/// 实例化一个自增信息的对象,包括最大值
/// </summary>
/// <param name="max">数据的最大值,必须指定</param>
/// <param name="start">数据的起始值,默认为0</param>
public SoftIncrementCount(long max, long start = 0)
{
this.start = start;
this.max = max;
current = start;
hybirdLock = new SimpleHybirdLock();
}
#endregion
#region Private Member
private long start = 0;
private long current = 0;
private long max = long.MaxValue;
private SimpleHybirdLock hybirdLock;
#endregion
#region Public Method
/// <summary>
/// 获取自增信息
/// </summary>
/// <returns>计数自增后的值</returns>
public long GetCurrentValue()
{
long value = 0;
hybirdLock.Enter();
value = current;
current += IncreaseTick;
if (current > max)
{
current = start;
}
hybirdLock.Leave();
return value;
}
/// <summary>
/// 重置当前序号的最大值
/// </summary>
/// <param name="max">最大值</param>
public void ResetMaxNumber(long max)
{
hybirdLock.Enter();
if (max > start)
{
if (max < current)
current = start;
this.max = max;
}
hybirdLock.Leave();
}
#endregion
#region Public Properties
/// <summary>
/// 增加的单元,如果设置为0,就是不增加。注意,不能小于0
/// </summary>
public int IncreaseTick { get; set; } = 1;
#endregion
#region Object Override
/// <summary>
/// 返回表示当前对象的字符串
/// </summary>
/// <returns>返回具体的值信息</returns>
public override string ToString()
{
return $"SoftIncrementCount[{this.current}]";
}
#endregion
#region IDisposable Support
private bool disposedValue = false; // 要检测冗余调用
void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
// TODO: 释放托管状态(托管对象)。
hybirdLock.Dispose();
}
// TODO: 释放未托管的资源(未托管的对象)并在以下内容中替代终结器。
// TODO: 将大型字段设置为 null。
disposedValue = true;
}
}
// TODO: 仅当以上 Dispose(bool disposing) 拥有用于释放未托管资源的代码时才替代终结器。
// ~SoftIncrementCount() {
// // 请勿更改此代码。将清理代码放入以上 Dispose(bool disposing) 中。
// Dispose(false);
// }
// 添加此代码以正确实现可处置模式。
/// <summary>
/// 释放当前对象所占用的资源
/// </summary>
public void Dispose()
{
// 请勿更改此代码。将清理代码放入以上 Dispose(bool disposing) 中。
Dispose(true);
// TODO: 如果在以上内容中替代了终结器,则取消注释以下行。
// GC.SuppressFinalize(this);
}
#endregion
}
}