流水號獲取的解決方案,流水號獲取
流水號的獲取在單機版的程序中只需要簡單的遞增就可以解決。但是在分布式系統中存在多個客戶端同時請求同一個流水號的問題,如果處理不好容易導致多個客戶端獲得同一個流水號。
解決方案一
在Oracle數據庫中有專門的序列管理sequence,具體的介紹在網上可以找到很多。但是在實際使用中存在很多的問題:
1、如果有很多個不同的序列,並且在需要根據時間變化(每天0點重置)時處理起來很麻煩。
2、隨時間增加數據庫中的序列越來越多。
3、在首次創建一個序列的時候需要激活後才能正常使用。
所以果斷放棄了這個方案。
解決方案二
大體的思路:在數據庫中專門建一個表存儲各類的序列,在服務器端創建一個服務專門提供各類序列當前的流水號。客戶端通過這個服務來獲取序列,不能直接去數據庫中查
第1步:在數據庫中專門創建一個新的表用來存儲這些序列。表結構如下:
1、FLAG(標志碼 主鍵):代表序列的標志
2、Sequence(當前的流水號):默認為0
3、UpdateTime(更新時間):根據自己的需要來創建
第2步:先創建一些接口
1、數據服務的接口

![]()
1 public interface IDataOperator
2 {
3 int ExecuteNonQuery(List<string> list);
4 int ExecuteNonQuery(string strSql);
5 int ExecuteNonQuery(List<string> list, ref string strError);
6 int ExecuteNonQuery(string strSql, ref string strError);
7 T ExecuteScalar<T>(string strSql);
8 T ExecuteScalar<T>(string strSql, ref string strError);
9 DataSet GetDataSet(string strSql);
10 DataSet GetDataSet(string strSql, ref string strError);
11 DataTable GetDataTable(string strSql);
12 DataTable GetDataTable(string strSql, ref string strError);
13 }
View Code
2、流水號的接口

![]()
1 public interface ISequence
2 {
3 int GetNext(string strFlag);
4 }
View Code
第3步:在服務器端創建一個服務,這個服務有兩個功能。我這邊客戶端和服務端的通信用的是Remoting技術。這裡就不展示相關的代碼了。
1、做客戶端的數據中轉,直接和數據庫服務器之間通信,

![]()
1 public class SqlServer : MarshalByRefObject,IDataOperator
2 {
3 #region 私有字段
4 private string strConn;
5 #endregion
6 /// <summary>
7 /// 構造器
8 /// </summary>
9 public SqlServer ()
10 {
11 strConn = string.Format(@"User ID={0};Password={1};Data Source={2};Pooling=true;Min Pool Size=0;Max Pool Size={3};",
12 “”,
13 “”,
14 “”
15 “”;
16
17 }
18 /// <summary>
19 /// 打開數據庫連接
20 /// </summary>
21 /// <param name="strError">返回錯誤信息</param>
22 /// <returns></returns>
23 public bool OpenTest(ref string strError)
24 {
25 bool blResult = false;
26 try
27 {
28 using (SqlConnection conn = new SqlConnection(strConn))
29 {
30 conn.Open();
31 conn.Close();
32 }
33 blResult = true;
34 }
35 catch(Exception ex)
36 {
37 strError = ex.Message;
38 }
39 return blResult;
40 }
41 /// <summary>
42 /// 執行一個SQL語句集合返回操作成功數
43 /// </summary>
44 /// <param name="strsql"></param>
45 /// <param name="parameter"></param>
46 /// <returns></returns>
47 public int ExecuteNonQuery(List<string> list, ref string strError)
48 {
49 int intResult = 0;
50 int i = 0;
51 if (list.Count > 0)
52 {
53 try
54 {
55 using (SqlConnection conn = new SqlConnection(strConn))
56 {
57
58 conn.Open();
59 SqlTransaction tran = conn.BeginTransaction();
60
61 try
62 {
63 using (SqlCommand cmd = conn.CreateCommand())
64 {
65 cmd.Transaction = tran;
66 for (i = 0; i < list.Count; i++)
67 {
68 cmd.CommandText = list[i].Trim();
69 intResult+= cmd.ExecuteNonQuery();
70 }
71 tran.Commit();
72 }
73
74 }
75 catch (Exception ex)
76 {
77 try
78 {
79 intResult = -1;
80 tran.Rollback();
81
82 strError =
83 string.Format("{0}個操作回滾成功!{1}\r\n ErrSQL:\r\n {2}",
84 i, ex.Message, list[i]);
85 }
86 catch(Exception ex2)
87 {
88 intResult = -2;
89 strError =
90 string.Format("{0}個操作回滾失敗!{1}\r\n ErrSQL:\r\n {2}",
91 i, ex2.Message, list[i]);
92 }
93 }
94 finally
95 {
96 conn.Close();
97 }
98 }
99 }
100 catch (SqlException ex)
101 {
102
103 strError = ex.Message;
104 }
105
106 }
107 else
108 {
109 strError = string.Format("ExecuteNonQuery(List<string> list):未傳入需要執行的SQL語句");
110 }
111 return intResult;
112
113 }
114 /// <summary>
115 /// 執行一個SQL語句集合返回操作成功數
116 /// </summary>
117 /// <param name="strsql"></param>
118 /// <param name="parameter"></param>
119 /// <returns></returns>
120 public int ExecuteNonQuery(List<string> list)
121 {
122 int intResult = 0;
123 int i = 0;
124 if (list.Count > 0)
125 {
126 using (SqlConnection conn = new SqlConnection(strConn))
127 {
128 conn.Open();
129 SqlTransaction tran = conn.BeginTransaction();
130 using (SqlCommand cmd = conn.CreateCommand())
131 {
132 try
133 {
134 cmd.Transaction = tran;
135 for (i = 0; i < list.Count; i++)
136 {
137 cmd.CommandText = list[i].Trim();
138 intResult += cmd.ExecuteNonQuery();
139 }
140 tran.Commit();
141 }
142 catch (Exception ex)
143 {
144 try
145 {
146 intResult = -1;
147 tran.Rollback();
148 PubLibrary.WriteTxt(
149 string.Format("{0}個操作回滾成功!{1}\r\n ErrSQL:\r\n {2}",
150 i, ex.Message, list[i]));
151 }
152 catch (Exception ex2)
153 {
154 intResult = -2;
155 PubLibrary.WriteTxt(
156 string.Format("{0}個操作回滾失敗!{1}\r\n ErrSQL:\r\n {2}",
157 i, ex2.Message, list[i]));
158 }
159 }
160 finally
161 {
162 conn.Close();
163 }
164
165 }
166
167 }
168 }
169 else
170 {
171 PubLibrary.WriteTxt("ExecuteNonQuery(List<string> list):未傳入需要執行的SQL語句");
172 //throw new SystemException(string.Format("ExecuteNonQuery(List<string> list):未傳入需要執行的SQL語句"));
173 }
174 return intResult;
175 }
176 /// <summary>
177 /// 返回操作成功數
178 /// </summary>
179 /// <param name="strSql"></param>
180 /// <returns></returns>
181 public int ExecuteNonQuery(string strSql)
182 {
183 int intResult = 0;
184 try
185 {
186 using (SqlConnection conn = new SqlConnection(strConn))
187 {
188 conn.Open();
189 using (SqlCommand cmd = conn.CreateCommand())
190 {
191 cmd.CommandText = strSql;
192
193 intResult = cmd.ExecuteNonQuery();
194 }
195 conn.Close();
196 }
197 }
198 catch (Exception ex)
199 {
200 PubLibrary.WriteTxt(ex.Message);
201 }
202 finally
203 {
204 //conn.Close();
205 }
206
207 return intResult;
208 }
209 /// <summary>
210 /// 返回操作成功數
211 /// </summary>
212 /// <param name="strSql"></param>
213 /// <returns></returns>
214 public int ExecuteNonQuery(string strSql, ref string strError)
215 {
216 int intResult =0;
217 try
218 {
219 using (SqlConnection conn = new SqlConnection(strConn))
220 {
221 conn.Open();
222 using (SqlCommand cmd = conn.CreateCommand())
223 {
224 cmd.CommandText = strSql;
225
226 intResult = cmd.ExecuteNonQuery();
227 }
228 conn.Close();
229 }
230 }
231 catch (Exception ex)
232 {
233 strError = ex.Message;
234 }
235 finally
236 {
237
238
239 }
240
241 return intResult;
242
243 }
244 /// <summary>
245 /// 返回紀錄集第一行第一列的數據
246 /// </summary>
247 /// <typeparam name="T"></typeparam>
248 /// <param name="strSql"></param>
249 /// <returns></returns>
250 public T ExecuteScalar<T>(string strSql)
251 {
252 T temp = default(T);
253 try
254 {
255 using (SqlConnection conn = new SqlConnection(strConn))
256 {
257 conn.Open();
258 using (SqlCommand cmd = conn.CreateCommand())
259 {
260
261 cmd.CommandText = strSql;
262
263 object o = cmd.ExecuteScalar();
264 if (o != null && o != DBNull.Value)
265 {
266 temp = (T)Convert.ChangeType(o, typeof(T));
267 }
268 }
269 conn.Close();
270 }
271
272
273 }
274 catch (SqlException ex)
275 {
276 PubLibrary.WriteTxt(ex.Message);
277 }
278 finally
279 {
280
281 }
282 return temp;
283
284 }
285
286 /// <summary>
287 /// 返回紀錄集第一行第一列的數據
288 /// </summary>
289 /// <typeparam name="T"></typeparam>
290 /// <param name="strSql"></param>
291 /// <param name="strError"></param>
292 /// <returns></returns>
293 public T ExecuteScalar<T>(string strSql, ref string strError)
294 {
295
296 T temp = default(T);
297 try
298 {
299 using (SqlConnection conn = new SqlConnection(strConn))
300 {
301 conn.Open();
302 using (SqlCommand cmd = conn.CreateCommand())
303 {
304
305 cmd.CommandText = strSql;
306
307 object o = cmd.ExecuteScalar();
308 if (o != null && o != DBNull.Value)
309 {
310 temp = (T)Convert.ChangeType(o, typeof(T));
311 }
312 }
313 conn.Close();
314 }
315 }
316 catch (SqlException ex)
317 {
318 strError = ex.Message;
319 }
320 finally
321 {
322
323 }
324 return temp;
325 }
326 /// <summary>
327 /// 獲取數據集
328 /// </summary>
329 /// <param name="strSql"></param>
330 /// <returns></returns>
331 public DataSet GetDataSet(string strSql)
332 {
333
334 DataSet ds = new DataSet();
335 try
336 {
337 using (SqlConnection conn = new SqlConnection(strConn))
338 {
339 conn.Open();
340 using (SqlCommand cmd = conn.CreateCommand())
341 {
342 cmd.CommandText = strSql;
343 SqlDataAdapter adapter = new SqlDataAdapter(cmd);
344 adapter.Fill(ds);
345 }
346 conn.Close();
347 }
348 }
349 catch (Exception ex)
350 {
351 PubLibrary.WriteTxt(ex.Message);
352 }
353 finally
354 {
355
356 }
357 return ds;
358 }
359
360 /// <summary>
361 /// 獲取數據集
362 /// </summary>
363 /// <param name="strSql"></param>
364 /// <param name="strError"></param>
365 /// <returns></returns>
366 public DataSet GetDataSet(string strSql,ref string strError)
367 {
368 DataSet ds = new DataSet();
369 try
370 {
371 using (SqlConnection conn = new SqlConnection(strConn))
372 {
373 conn.Open();
374 using (SqlCommand cmd = conn.CreateCommand())
375 {
376 cmd.CommandText = strSql;
377 SqlDataAdapter adapter = new SqlDataAdapter(cmd);
378 adapter.Fill(ds);
379 }
380 conn.Close();
381 }
382 }
383 catch (Exception ex)
384 {
385 strError = ex.Message;
386 }
387
388 return ds;
389 }
390
391 /// <summary>
392 /// 獲取第一張數據表
393 /// </summary>
394 /// <param name="strSql"></param>
395 /// <returns></returns>
396 public DataTable GetDataTable(string strSql)
397 {
398 DataTable dt = new DataTable();
399 try
400 {
401 using (SqlConnection conn = new SqlConnection(strConn))
402 {
403 conn.Open();
404 using (SqlCommand cmd = conn.CreateCommand())
405 {
406 cmd.CommandText = strSql;
407
408 SqlDataAdapter adapter = new SqlDataAdapter(cmd);
409 DataSet ds = new DataSet();
410 adapter.Fill(ds);
411 if (ds != null && ds.Tables.Count > 0)
412 {
413 dt = ds.Tables[0];
414 }
415 }
416 conn.Close();
417 }
418
419 }
420 catch (Exception ex)
421 {
422 PubLibrary.WriteTxt(ex.Message);
423 }
424
425
426 return dt;
427 }
428
429 /// <summary>
430 /// 獲取第一張數據表
431 /// </summary>
432 /// <param name="strSql"></param>
433 /// <param name="strError"></param>
434 /// <returns></returns>
435 public DataTable GetDataTable(string strSql,ref string strError)
436 {
437 DataTable dt = new DataTable();
438 try
439 {
440 using (SqlConnection conn = new SqlConnection(strConn))
441 {
442 conn.Open();
443 using (SqlCommand cmd = conn.CreateCommand())
444 {
445 cmd.CommandText = strSql;
446 SqlDataAdapter adapter = new SqlDataAdapter(cmd);
447 DataSet ds = new DataSet();
448 adapter.Fill(ds);
449 if (ds != null && ds.Tables.Count > 0)
450 {
451 dt = ds.Tables[0];
452 }
453 }
454 conn.Close();
455 }
456 }
457 catch (Exception ex)
458 {
459 strError = ex.Message;
460 }
461 finally
462 {
463
464 }
465 return dt;
466 }
467
468
469 }
View Code
2、創建流水號的類, “_nextTen += 10;//如果流水號獲取很頻繁這個值可以設大一點”這裡相當於一個緩存機制,以減少對數據庫的訪問量。可以根據實際需求來增大或減少。這裡要注意一點如果服務有重啟會有部分流水號丟失。如果是對流水號的連續性要求高的最好設置為1,但是這樣對數據庫的訪問量會非常大。會導致獲取流水號的平均時間增加,我的測試(普通台式電腦做服務器同時有30個進程在獲取同一個流水號)是在10個緩存的情況下平均時間是10ms以內。

![]()
1 public class BCSequence
2 {
3 private string _strFlag;
4 IDataOperator dataOperator;
5 public BCSequence(IDataOperator dataOperator)
6 {
7 this.dataOperator = dataOperator;
8 }
9 public BCSequence(string strFlag, int intSequence, IDataOperator dataOperator)
10 {
11 this._strFlag = strFlag;
12 this._intSequence = intSequence;
13 this._nextTen = intSequence;
14 this.dataOperator = dataOperator;
15
16 }
17
18 public string StrFlag
19 {
20 get { return _strFlag; }
21 set { _strFlag = value; }
22 }
23 int _intSequence;
24 int _nextTen
25 {
26 get;
27 set;
28 }
29
30
31 /// <summary>
32 /// 流水號保存不了則返回-1
33 /// </summary>
34 public int Next
35 {
36 get
37 {
38 if (_intSequence >= _nextTen)
39 {
40 _nextTen += 10;//如果流水號獲取很頻繁這個值可以設大一點
41 if (SaveInfo() <= 0)
42 {
43 _nextTen -= 10;//保存失敗必須將值變回10否則會出現重碼的情況
44 return -1;
45
46 }
47 }
48 _intSequence++;
49 return _intSequence;
50 }
51 }
52 public int SaveInfo()
53 {
54 int intResult = -1;
55 try
56 {
57 string strSql = string.Format(@"Select Count(*) from HT_Barcode_Sequence where Flag='{0}'", StrFlag);
58
59 intResult = dataOperator.ExecuteScalar<int>(strSql);
60 if (intResult == 0)
61 {
62 strSql =
63 string.Format(@"Insert into HT_Barcode_Sequence(Flag,Sequence,Update_Time)values('{0}',{1},Now())",
64 _strFlag, _nextTen);
65 }
66 else
67 {
68 strSql =
69 string.Format(@"Update HT_Barcode_Sequence set Sequence={0},Update_Time=Now() where Flag='{1}'",
70 _nextTen, _strFlag);
71 }
72 intResult = dataOperator.ExecuteNonQuery(strSql);
73 }
74 catch (Exception ex)
75 {
76 //PubLibrary.WriteTxt(ex.Message);
77 }
78
79 return intResult;
80
81 }
82 public static BCSequence CreatSeq(string strFlag, IDataOperator dataOperator)
83 {
84 BCSequence BCSeq = null;
85 try
86 {
87 //PBSSQLServer pbssql = new PBSSQLServer();
88 string strSql = string.Format(@"Select Flag,Sequence,Update_Time from HT_Barcode_Sequence where Flag='{0}'",
89 strFlag);
90 using (DataTable dt = dataOperator.GetDataTable(strSql))
91 {
92 if (dt != null && dt.Rows.Count > 0)
93 {
94 int intSequence = DataConvert.DbToInt(dt.Rows[0]["Sequence"]);
95 BCSeq = new BCSequence(strFlag, intSequence,dataOperator);
96 }
97 else
98 {
99 BCSeq = new BCSequence(strFlag, 0,dataOperator);
100 if (BCSeq.SaveInfo() <= 0)
101 {
102 BCSeq = null;
103 }
104 }
105 }
106 }
107 catch (Exception ex)
108 {
109 //PubLibrary.WriteTxt(ex.Message);
110 }
111
112 return BCSeq;
113 }
114
115
116 }
View Code
3、管理所有的流水號,客戶端要獲取流水號需要依靠這個服務

![]()
1 public class BarcodeSequence:MarshalByRefObject,ISequence
2 {
3
4 public BarcodeSequence()
5 {
6
7 }
8 /// <summary>
9 ///
10 /// </summary>
11 /// <param name="strFlag"></param>
12 /// <returns>返回相應標志碼的流水號,如果數據庫交互出現問題得不到標志碼的流水號,或創建不了標志碼。則返回-2</returns>
13 public int GetNext(string strFlag)
14 {
15 BCSequence bs = Get(strFlag);
16 if (bs == null)
17 {
18 bs = Creat(strFlag);
19 //將新創建的標志碼類放入隊列的工作交給創建器
20 }
21 if (bs != null)
22 {
23 return bs.Next;
24 }
25 else //如果數據庫交互出現問題得不到標志碼的流水號,或創建不了標志碼。則返回-2
26 {
27 return -2;
28 }
29 }
30 /// <summary>
31 /// 標志碼生成器
32 /// </summary>
33 /// <param name="strFlag"></param>
34 /// <returns></returns>
35 public BCSequence Creat(string strFlag)
36 {
37 lock (PubLibrary.CreatObj)
38 {
39 BCSequence bs = Get(strFlag);
40 if (bs == null)
41 {
42 bs= BCSequence.CreatSeq(strFlag,new SQLServer());
43
44 if (bs != null)
45 {
46 PubLibrary.lstSeq.Add(bs);
47 }
48 }
49 return bs;
50 }
51
52 }
53
54 /// <summary>
55 /// 獲取標志碼列表中對應的標志碼
56 /// </summary>
57 /// <param name="strFlag">要查詢的標志碼</param>
58 /// <returns></returns>
59 public BCSequence Get(string strFlag)
60 {
61 BCSequence bs = null;
62 foreach (BCSequence bcbs in PubLibrary.lstSeq)
63 {
64 if (bcbs.StrFlag == strFlag)
65 {
66
67 bs = bcbs;
68 break;
69 }
70 }
71 return bs;
72 }
73
74 }
View Code
還有一個靜態類專門存儲現在在使用的一些流水號列表等信息

![]()
1 public class PubLibrary
2 {
3
4 public static object CreatObj=new object();
5 ///// <summary>
6 ///// 提供給服務內部的類查詢數據使用的SQLServer
7 ///// </summary>
8 //public static SQLServer pbsSQL = new SQLServer();
9
10 public static List<BCSequence> lstSeq = new List<BCSequence>();
11
12 public static void RegistRemotingObject()
13 {
14
15 string strServicename = "";
16 string strChannelType ="";
17 int intChannelNo =Convert.ToInt32("");;
18 string strCallType = "SingleCall";
19 int intInitialLeaseTime = Convert.ToInt32("");
20 int intSponsorshipTimeout =Convert.ToInt32("");
21 int intRenewOnCallTime =Convert.ToInt32("");
22 string strSeqServicename ="";
23 string strSeqChannelType = "";
24 int intSeqChannelNo = Convert.ToInt32("");
25 string strSeqInfo = "";
26 string strSeqCallType = "SingleCall";
27 int intSeqInitialLeaseTime = Convert.ToInt32("");
28 int intSeqSponsorshipTimeout = Convert.ToInt32("");
29 int intSeqRenewOnCallTime = Convert.ToInt32("");
30 try
31 {
32 CreateRemotingObject<SQLServer>(intChannelNo, strCallType, strServicename, strChannelType, intInitialLeaseTime, intSponsorshipTimeout, intRenewOnCallTime);
33 PubLibrary.WriteTxt(string.Format("已經注冊類型SQLServer {0},{1},{2},{4},{5},{6}",intChannelNo, strCallType, strServicename, strChannelType, intInitialLeaseTime, intSponsorshipTimeout, intRenewOnCallTime ));
34
35 CreateRemotingObject<BarcodeSequence>(intSeqChannelNo, strSeqCallType, strSeqServicename, strSeqChannelType, intSeqInitialLeaseTime, intSeqSponsorshipTimeout, intSeqRenewOnCallTime);
36 PubLibrary.WriteTxt(string.Format("已經注冊類型BarcodeSequence {0},{1},{2},{4},{5},{6}", intSeqChannelNo, strSeqCallType, strSeqServicename, strSeqChannelType, intSeqInitialLeaseTime, intSeqSponsorshipTimeout, intSeqRenewOnCallTime));
37
38 }
39 catch (Exception ex)
40 {
41 PubLibrary.WriteTxt(ex.Message);
42 }
43 }
44
45 /// <summary>
46 /// 清除遠程對象
47 /// </summary>
48 public static void ClearRemotingObject()
49 {
50 try
51 {
52 MES.EI.RemotingOperation.UnregisterChannel();
53 }
54 catch (Exception ex)
55 {
56 PubLibrary.WriteTxt(ex.Message);
57 }
58 }
59
60 /// <summary>
61 /// 以Append的模式往指定的文本文件寫入文本信息
62 /// </summary>
63 /// <param name="Info" >信息</param>
64 public static void WriteTxt(string Info)
65 {
66 string filename = Service.StartPath + "Error_" + System.DateTime.Now.ToString("yyyyMMdd") + ".txt";
67
68 if (filename.Substring(filename.Length - 3).ToUpper() == "TXT")
69 {
70 lock (typeof(PubLibrary))
71 {
72 System.IO.FileStream s = System.IO.File.Open(filename, System.IO.FileMode.Append);
73 System.IO.StreamWriter w = new System.IO.StreamWriter(s);
74 w.WriteLine(System.DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss") + ":" + Info);
75 w.Close();
76 }
77 }
78 else
79 {
80 throw new ApplicationException(filename + " isn't a txt file.");
81 }
82 }
83 /// <summary>
84 /// 把相關信息寫入事件日志
85 /// </summary>
86 /// <param name="Info">信息</param>
87 /// <param name="type">事件類型</param>
88 public static void WriteEvent(string Info, System.Diagnostics.EventLogEntryType type)
89 {
90 Service.ServiceLog.WriteEntry(Info, type);
91 }
92
93 /// <summary>
94 /// 根據指定參數創建遠程對象
95 /// </summary>
96 /// <typeparam name="T">Remoting服務的數據類型</typeparam>
97 /// <param name="Port">端口</param>
98 /// <param name="CallType">激活類型</param>
99 /// <param name="RemotingServerName">遠程服務名稱</param>
100 /// <param name="ChannelType">通道類型</param>
101 /// <param name="InitialLeaseTime">租約的初始時間</param>
102 /// <param name="SponsorshipTimeout">等待主辦方返回租約續訂時間的時間</param>
103 /// <param name="RenewOnCallTime">對象重新調用時增加的生存期</param>
104 private static void CreateRemotingObject<T>(int Port, string CallType, string RemotingServerName, string ChannelType,
105 int InitialLeaseTime, int SponsorshipTimeout, int RenewOnCallTime)
106 {
107 try
108 {
109 RemotingChannelType[] channeltypes = RemotingServerInfo.GetChannelTypeFromString(ChannelType);
110
111 if (channeltypes != null && channeltypes.Length > 0)
112 {
113 RemotingServerInfo remotinginfo = new RemotingServerInfo
114 (Port, CallType, RemotingServerName, channeltypes);
115
116 RemotingEventInfo eventinfo = new RemotingEventInfo
117 (HTPBSService.ServiceLog, System.Diagnostics.EventLogEntryType.Information,
118 InitialLeaseTime, SponsorshipTimeout, RenewOnCallTime);
119
120 RemotingOperation.CreateRemotingServerFullDeserialization<T>(remotinginfo, eventinfo);
121 }
122 }
123 catch (System.Exception ex)
124 {
125 PubLibrary.WriteTxt(
126 string.Format("{0}:服務不能啟動,因為{1} {2}", DateTime.Now.ToString(), ex.Message, ex.StackTrace));
127 }
128 }
129 }
View Code
第4步:創建客戶端

![]()
1 public class SqlSequence :IClientSequence
2 {
3 ISequence se;
4 private string strMachineNo;
5 private int intChannelNo;
6 private string strServiceName;
7 /// <summary>
8 /// 構造器
9 /// </summary>
10 /// <param name="MachineNo">服務器電腦名</param>
11 /// <param name="ChannelNo">服務端口</param>
12 /// <param name="ServiceName">服務名</param>
13 public SqlSequence(string MachineNo, int ChannelNo, string ServiceName)
14 {
15 this.strMachineNo = MachineNo;
16 this.intChannelNo = ChannelNo;
17 this.strServiceName = ServiceName;
18 }
19 /// <summary>
20 /// 打開到遠程服務器的通道
21 /// </summary>
22 /// <returns></returns>
23 public bool OpenRemoting()
24 {
25 try
26 {
27 RemotingClientInfo clientinfo;
28 clientinfo = new RemotingClientInfo(strMachineNo,
29 intChannelNo,
30 strServiceName,
31 RemotingChannelType.Tcp);
32 GetRemotingVoucher(ref clientinfo);
33 se = RemotingOperation.CreateRemotingClient<ISequence>(clientinfo);
34
35 return true;
36 }
37 catch (Exception ex)
38 {
39 //PubLibrary.WriteTxt(ex.Message);
40 return false;
41 }
42 }
43
44
45 public bool GetNext(string strFlag, out int index, ref string strError)
46 {
47 bool blResult = false;
48 index = -1;
49 try
50 {
51 index = se.GetNext(strFlag);
52 if (index != -1)
53 {
54 blResult = true;
55 }
56 else
57 {
58 strError = "服務端出現錯誤無法獲取流水號";
59 }
60 }
61 catch (Exception ex)
62 {
63
64 if (ex.Message.Contains("由於目標計算機積極拒絕"))
65 {
66
67 string strName = System.Net.Dns.GetHostEntry(ex.Message.Split(' ')[1].Split(':')[0]).HostName.Split('.')[0];
68 strError = "由於服務器[" + strName + "]上的噴碼服務已停止\r\n\r\n暫時無法噴印,請聯系管理員開啟噴碼服務";
69 }
70 else
71 {
72 strError = ex.Message;
73 }
74
75 }
76 return blResult;
77 }
78 /// <summary>
79 /// 指定遠程連接時客戶端信息
80 /// </summary>
81 /// <param name="clientinfo"></param>
82 private void GetRemotingVoucher(ref RemotingClientInfo clientinfo)
83 {
84 //clientinfo.IsTrusty = true;
85 //if (!clientinfo.IsTrusty)
86 //{
87 clientinfo.IsTrusty = false;
88 clientinfo.UserName = "BMES";
89 clientinfo.Password = "Battery123";
90 clientinfo.Domain = "";
91 //}
92 }
93
94 /// <summary>
95 /// 關閉遠程通道
96 /// </summary>
97 public void CloseRemoting()
98 {
99
100 RemotingOperation.UnregisterChannel();
101
102 se = null;
103 }
104 }
View Code
第5步:測試

![]()
1 SqlSequence BSeq = new SqlSequence(strSeqMachineName, intSeqChannel, strSeqServerName);
2
3 string strFlag ="";
4
5 int index = 0;
6
7 if( BSeq.GetNext(strFlag, out index, ref strError))
8
9 {
10
11 //成功
12
13 }
14
15 else
16
17 {
18
19 //失敗
20
21 }
View Code