本執行個體的代碼請看上篇部落格《AJAX執行個體之股票即時資訊顯示》。雖然Java和C#兩門語言文法非常相似,但是細節上還是有很多不同之處,所以在轉換的過程中,還是有幾個問題:
- Java下有HttpServlet,C#下的一般處理常式
- Java下有HashMap,C#下的Dictionary
- Java下有Random類有nextBoolean(),C#靈活使用nextDouble()
- Java下有Timer使用匿名函數,C#使用委託
不同 一般處理常式
HttpServlet專門用於響應請求的類,最開始我用的是Asp.net下的Web表單,但Web表單很明顯更傾向於可視,而這個例子所要求的服務端不必有頁面,所以使用的是一般處理常式(*.ashx),這個和HttpServlet非常類似,可以專門用於處理簡單的請求,相對於Web表單更省資源且響應速度更快。
Dictionary
C#沒有HashMap,不過可以使用其Dictionary達到同樣的效果,Dictionary存放的同樣是索引值對組合,當然值可以為物件類型。
NextBoolean()
Java下可以根據nextBoolean()決定是漲是降。
// 建立一個產生隨機數的對象 final Random random = new Random();//上漲或下降if (random.nextBoolean()) {sz = 0 - sz;}
C#呢?這可以靈活使用nextDouble(),nextDouble()取值為0~1,與0.5比較同樣可以決定是漲還是降。
Random rdm = new Random(); //上漲浮動 if (rdm.NextDouble() > 0.5) { sz = 0 - sz; }
匿名函數
好吧,前三個問題很簡單,第四個就比較困難了,先看一下未解決以前的計時代碼(服務端部分代碼):
/// <summary> /// 初始化配置資料 /// </summary> public void InitNew() { //設定股票字典 stock = new Dictionary<string, Stock>(); stock.Add("300001", szzs); stock.Add("600000", pfyh); stock.Add("601398", gsyh); stock.Add("601857", zgsy); //設定計時器參數 timer = new System.Timers. Timer(); timer.Enabled = true; timer.Interval = 50; //執行計時器函數theout timer.Elapsed +=new System.Timers.ElapsedEventHandler(theout); } /// <summary> /// 計時器執行函數 /// </summary> /// <param name="source">事件來源</param> /// <param name="e">事件參數</param> public void theout( object source,System.Timers.ElapsedEventArgs e) { //股票變動範圍 Random rdm = new Random(); double rdm2 = rdm.NextDouble(); //上漲浮動 double sz = rdm2 * 30; double pf = rdm2 * 0.5; double gs = rdm2 * 0.1; double zg = rdm2 * 0.3; //下跌浮動 if (rdm2 > 0.5) { sz = 0 - sz; } if (rdm2 > 0.5) { pf = 0 - pf; } if (rdm2 > 0.5) { gs = 0 - gs; } if (rdm2 > 0.5) { zg = 0 - zg; } //當前股票價格 szzs.SetCurrent(Math.Round((szzs.GetCurrent() + sz) * 100) / 100.0); pfyh.SetCurrent(Math.Round((pfyh.GetCurrent() + pf) * 100) / 100.0); gsyh.SetCurrent(Math.Round((gsyh.GetCurrent() + gs) * 100) / 100.0); zgsy.SetCurrent(Math.Round((zgsy.GetCurrent() + zg) * 100) / 100.0); }
沒有加用戶端代碼,直接運行服務端代碼,運行結果是:
這是我們比較常用的委託方式,但是很明顯,股票浮動值屬性"ran"讀取不出來,如果你把代碼放到VS中逐過程調試會發現:程式會在theout事件中隨機的重複執行。
更改後的代碼為:
/// <summary> /// 初始化配置資料 /// </summary> private void Init() { //建立四支股票 Stock szzs = new Stock("300001", "上證指數", 300); Stock pfyh = new Stock("600000", "浦發銀行", 25); Stock gsyh = new Stock("601398", "工商銀行", 6.5); Stock zgsy = new Stock("601857", "中國石油", 19.1); //設定股票字典 stock = new Dictionary<string, Stock>(); //添加股票 stock.Add("300001", szzs); stock.Add("600000", pfyh); stock.Add("601398", gsyh); stock.Add("601857", zgsy); //設定計時器參數,不要太大 timer = new System.Timers.Timer(50); timer.Enabled = true; //執行計時器函數theout Random rdm = new Random(); //每次只去一個,防止迴圈執行擷取隨機數 double mdr = rdm.NextDouble(); //timer的振蕩事件,採用匿名函數方式執行 timer.Elapsed += delegate(object source, System.Timers.ElapsedEventArgs e) { //股票變動範圍 //上漲浮動 double sz = mdr * 30; double pf = mdr * 0.5; double gs = mdr * 0.1; double zg = mdr * 0.3; //下跌浮動 if (mdr > 0.5) { sz = 0 - sz; } if (mdr > 0.5) { pf = 0 - pf; } if (mdr > 0.5) { gs = 0 - gs; } if (mdr > 0.5) { zg = 0 - zg; } //當前股票價格 szzs.SetCurrent(Math.Round((szzs.GetCurrent() + sz) * 100) / 100.0); pfyh.SetCurrent(Math.Round((pfyh.GetCurrent() + pf) * 100) / 100.0); gsyh.SetCurrent(Math.Round((gsyh.GetCurrent() + gs) * 100) / 100.0); zgsy.SetCurrent(Math.Round((zgsy.GetCurrent() + zg) * 100) / 100.0); }; }
運行結果為:
可以看到這次就能讀取到股票浮動欄位"ran"了,在VS中逐過程調試也會發現,每次計時器的振蕩事件代碼只執行一次。
比較一下這兩段代碼的不同,差別僅是在計時器振蕩事件代碼的位置:第一段的時鐘事件代碼放到了theout事件中,而第二段代碼則放到了匿名函數中,看似差別不大,但是這裡涉及到了變數的範圍問題,第一段代碼中,如果想使用
Stock szzs = new Stock("300001", "上證指數", 300); Stock pfyh = new Stock("600000", "浦發銀行", 25); Stock gsyh = new Stock("601398", "工商銀行", 6.5); Stock zgsy = new Stock("601857", "中國石油", 19.1);
這個變數,只能將其放到函數或事件外,用作全域變數;且
Random rdm = new Random(); double rdm2 = rdm.NextDouble();
這兩行代碼放到theout中和匿名函數中也會有不同的運行結果。
重複執行
上面說到重複執行的問題,甚至會在
/// <summary> /// 計時器執行函數 /// </summary> /// <param name="source">事件來源</param> /// <param name="e">事件參數</param> public void theout( object source,System.Timers.ElapsedEventArgs e) { //股票變動範圍 Random rdm = new Random(); double rdm2 = rdm.NextDouble(); //上漲浮動 double sz = rdm2 * 30; double pf = rdm2 * 0.5; double gs = rdm2 * 0.1; double zg = rdm2 * 0.3;}
這幾行代碼之間無規律跳動執行,這個問題並沒有解決,但是因為使用了匿名函數的方法,所以在整體功能實現上並沒有問題,如果您知道問題所在,歡迎指教,問題代碼:http://download.csdn.net/detail/lidaasky/4936350。