C#與NDde-如何連結超級大三元
續前文(台証超級大三元DDE)從Excel中找到需要的項目運算式,接著便是用C#與NDde去連結那些項目,以下就Visual C# 2008 Express為開發工具記錄作法。
0. 先啟動並登入台証超級大三元
1. 開啟新專案Windows Form應用程式
2. 在右邊方案總管的參考上按右鍵選加入參考
3. 瀏覽到下載NDde的路徑,撰擇NDde.dll
4. 從左邊工具箱中拉三個Label到Form1裡
5. 在右邊方案總管的Form1.cs上按右鍵選檢視程式碼
6. 最後複製並貼上下述範例代碼
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using NDde.Client; namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); //超級大三元每一個item都需要建立一個DDE連結,所以用陣列的方式建了三個 //如何找到大三元的連結參數TS及KS就不贅述了,請自行參閱blog文(台証超級大三元DDE) DdeClient[] ddecon = new DdeClient[3] { new DdeClient("TS", "KS"), new DdeClient("TS", "KS"), new DdeClient("TS", "KS") }; for (int i=0;i<3;i++) { try { ddecon[i].Connect(); } catch (Exception e) { MessageBox.Show(e.ToString()); } } //連結並關注item,以下item分別表示時間、成交價及單量 //如何找到TXFL9.123等連結參數就不贅述了,請自行參閱blog文(台証超級大三元DDE) ddecon[0].StartAdvise("TXFL9.123", 1, true, 60000); ddecon[0].Advise += OnAdvise; ddecon[1].StartAdvise("TXFL9.124", 1, true, 60000); ddecon[1].Advise += OnAdvise; ddecon[2].StartAdvise("TXFL9.128", 1, true, 60000); ddecon[2].Advise += OnAdvise; } private void OnAdvise(object sender, DdeAdviseEventArgs args) { //如果NDde有通知參數值有異動,就更改label值 if (args.Item == "TXFL9.123") myUI(args.Text, label1); else if (args.Item == "TXFL9.124") myUI(args.Text, label2); else if (args.Item == "TXFL9.128") myUI(args.Text, label3); } //Form上變更Text函數,請參閱http://www.dotblogs.com.tw/yc421206/archive/2009/02/13/7141.aspx private delegate void myUICallBack(string myStr, Control ctl); private void myUI(string myStr, Control ctl) { if (this.InvokeRequired) { myUICallBack myUpdate = new myUICallBack(myUI); this.Invoke(myUpdate, myStr, ctl); } else { ctl.Text = myStr; } } } }
7. 執行結果
Hi, 請記得 “Keep” 住 Dde Connection,也就是要能保持為 “Stateful” 狀態喔。 🙂
…我剛設了一個按鈕,去測每個連結的是否IsConnected,都回傳為True,過十分鐘去押也一樣為True,應該表示都一直有在連線,也能用該連線再去StartAdvise其它item並取得資料,就我的觀點是有維持住Dde Connection了…
但您的意思,似乎還有其它動作要做才算keep住Dde Connection?
煩請指導,感謝
思考一下,DdeClient[] 這個 Array 有確實被 Form1 給 Keep 住嗎?
從你上述列出的 partial 程式碼, I don’t think so….
是否這些 DDe connection instances 在過程中有被系統 GC(Garbage Collection) 掉了呢?
看你的寫法,好像都是偏向 Form-based 的程序性寫作,建議還是要有物件的基本思維邏輯,這樣比較容易懂得物件與物件之間的訊息溝通,以及物件的生命週期觀念。
呃,上述程式碼是簡單的範例供使用者參考,所以並沒有想那麼多…
在原本的實作上,我是另外寫成物件去call的,因為還要同時連結其它券商的DDE server,所以寫成物件會比較方便…
但您提到的重點,物件生命週期及GC,確實是我沒有去研究的地方…
感謝您的留言指導^^
先不論我原本失敗的實作,我剛搜尋了一下,在C#中,陣列即是物件,該物件若有被持續參考使用到,就不會有GC的問題(至少以往我在java寫作程式時是這樣,雖然沒碰它的UI)…
但您留言重點好像是落在Form本身是否有在keep物件…
註:使用本文範例,可能是今日期貨成交量不高的關係,所以數字很順地一直在跳動,沒有發生您說的GC或是DDE connection可能遺失的問題…
應該是這樣吧:
private DdeClient[] ddecon;
public Form1()
{
ddecon = new DdeClient[3] { …….}
}
這個宣告是要在放在 Class-level,而不是在 constructor 內宣告才是。
這也是我一再提醒, Form1 與 dde connection,生命週期一定要相等的意思。 否則,系統哪時候 GC 回收,都說不定的。
看看是否這樣。 若還有問題,可以 Email 給我。
嗯,我了解您的意思了…
我原本的實作DdeClient的確是放在Form1外,這個範例比較偷懶沒去注意那麼多…^^”
只是,看來仍無法解決我之前做白工的問題T_T
題外話,C#我是不熟,上述範例以資深程式設計的角度來講,確實不夠工整,但我覺得除非關掉Form1,那麼系統沒道理會去對Form1做GC回收,畢竟Form1是使用者一直在執行的介面,如果我不定時的要用到Form1物件做些事情怎麼辦?
所以就本文範例來講,關掉Form1等於是關掉DDE connection,生命週期是相等的…(範例沒個人家寫好還狡辯^^”,請笑笑看看這段話就好)
很高興您能撥空與我交流,日後有問題再至您blog打擾^^
首先感謝您的程式碼 受益良多
我個人不喜歡用.StartAdvise這個方法 我有些功能需要把DDE關掉 重新叫起會有delay 有時後還會當掉
我之前引用日盛的DDE 都是用.Request這個方法 需要再去抓 抓日盛的DDE資料都沒問題 抓凱基的就抓不到了 請問版大有什麼辦法可以克服嗎?
感謝
請問 DDE 連線後 , 報價顯示後並劃出一個走勢圖或一分K棒圖怎樣寫?
為什麼使用你的程式碼,我改為康和連結DDE後 報價都會延遲出來,有時候只有2個報價,查了好多遍?不知道出在哪裡?