WCF DateSet應(yīng)用技巧詳解
WCF開發(fā)工具是.NET Framework 3.5中的一個重要的組成部分,我們可以通過它的幫助來實現(xiàn)許多需求。在這里我們可以先來了解一下WCF DateSet的相關(guān)概念,希望可以幫助我們來解決一些問題。
這幾天看了WCF相關(guān)的資料,然后就產(chǎn)生一個想法.如何實現(xiàn)WCF實現(xiàn)傳輸DataSet,這個服務(wù)的主要功能是客戶端調(diào)用服務(wù)端的一個函數(shù),這個函數(shù)接受一個DataSet的參數(shù),然后再返回一個DataSet,當(dāng)然這個功能很簡單,幾行代碼就搞定了.可是當(dāng)如果DataSet內(nèi)的數(shù)據(jù)量非常大的時候,那就麻煩了.(暫不討論傳輸大數(shù)據(jù)量的DataSet是否合理),WCF默認(rèn)最大傳輸數(shù)據(jù)量為64K,當(dāng)然可以實現(xiàn)修改配置文件來傳輸大數(shù)據(jù)量,可是不能解決本質(zhì)的問題,我目前解決這個問題的方式是,把一個DataSet序列化為一個字節(jié),然后把這些字節(jié)進(jìn)行壓縮,然后每次發(fā)送一小段字節(jié)回去,接受到這個些字節(jié)以后然后在解壓縮,再反序列化為為DataSet,這樣就實現(xiàn)了,傳入一個WCF DateSet然后再返回一個DataSet,這樣的話,就需要用到WCF的雙向通信,使用回調(diào)函數(shù)。
- DuplexChannelFactory<IHello> channelFactory = new DuplexChannelFactory
<IHello>(new InstanceContext(new ClientCallBack()), "defaultEndpoint");- IHello getHello = channelFactory.CreateChannel();
- //傳入DataSet到服務(wù)端
- getHello.SayHelloTo();
- 首先客戶端調(diào)用服務(wù)端的函數(shù)SayHelloTo(),
- public void SayHelloTo()
- {
- //讀取客戶端傳入的WCF DateSet
- #region 服務(wù)端的數(shù)據(jù)
- ICallback callback = OperationContext.Current.GetCallbackChannel
<ICallback>();- int intNum = callback.getTimes() + 1; //獲取讀取字節(jié)流的次數(shù)
- MemoryStream Mstream = new MemoryStream();
- byte[] getbyte;
- for (int i = 1; i < intNum; i++)
- {
- getbyte = callback.getBytes(i);
- Mstream.Write(getbyte,0,getbyte.Length);//寫到內(nèi)存中
- }
- Mstream.Position = 0;
- getbyte = new byte[Mstream.Length];
- Mstream.Read(getbyte, 0, getbyte.Length);//從內(nèi)存中讀到getbyte中
- Mstream.Close();
- //反序列化
- ServiceData = KCDataFormatter.RetrieveDataSetDecompress(getbyte);
- //----------------------------
- //此處得到序列化以后的字節(jié),可以再反序列化為DataSet,
得到DataSet就可以對個DataSet做處理,刪除,修改,- //處理完成再把處理完成的DataSet賦值給ServiceData,就可以了
- //----------------------------
- #endregion
- }ICallback callback = OperationContext.Current.
GetCallbackChannel<ICallback>();- 此時就會調(diào)用客戶端的回調(diào)函數(shù)
- public class ClientCallBack : ICallback
- {
- #region ICallBack 成員
- //要上傳的數(shù)據(jù)
- public void getData()
- {
- DataSet ds = new DataSet("test");
- DataTable table = new DataTable("test");
- DataColumn column = new DataColumn("test");
- column.DataType = Type.GetType("System.String");
- table.Columns.Add(column);
- DataRow row;
- for (int i = 0; i < 200000; i++)
- {
- row = table.NewRow();
- row["test"] = "Hello";
- table.Rows.Add(row);
- }
- ds.Tables.Add(table);
- byte_All = KCDataFormatter.GetBinaryFormatDataCompress(ds);
- }
- private int i = 1000; //每次讀取字節(jié)的數(shù)量
- byte[] byte_All;//獲取要上傳的字節(jié)流
- MemoryStream Mstream;//流
- public byte[] getBytes(int intNum)
- {
- int j = 1000;
- byte[] buffer;
- if (intNum < iti) //判斷是否是最后一次循環(huán)
- {
- buffer = new byte[1000];
- }
- else
- {
- int nn = byte_All.Length - ((iti - 1) * 1000);
- buffer = new byte[nn];
- j = nn;
- }
- int iold = (i * (intNum - 1)); //記錄上一次的字節(jié)位置
- Mstream = new MemoryStream();
- Mstream.Write(byte_All, iold, j);//從byte_All中
的第iolld開始寫入j(最多不超過)個到內(nèi)存中- buffer = Mstream.ToArray();
- Mstream.Close();
- Mstream.Dispose();
- return buffer;
- }
- private int iti = 0; //初始化循環(huán)次數(shù)
- public int getTimes() //將數(shù)據(jù)流分為多少部分
- {
- getData();
- int temp = byte_All.Length / 1000;
- int intNum = byte_All.Length % 1000 != 0 ? temp + 1 : temp;
- iti = intNum;
- return intNum;
- }
- #endregion
- }
getData()函數(shù)內(nèi)可以編寫需要上傳的WCF DateSet,我這里是生成20W條記錄.通過回調(diào)函數(shù)就會把這20W條數(shù)據(jù)傳入服務(wù)端,回調(diào)結(jié)束了,DataSet也就傳入了服務(wù)端了.(我這里服務(wù)端沒有任何處理這個DataSet就直接返回這個DataSet會客戶端),客戶端繼續(xù)執(zhí)行他的邏輯,此時的邏輯是把剛才傳入的服務(wù)端的Dataset再返回給客戶端
- //獲取服務(wù)端返回的DataSet
- int intNum = getHello.serviceTime() + 1; //獲取讀取字節(jié)流的次數(shù)
- MemoryStream Mstream = new MemoryStream();
- byte[] getbyte;
- for (int i = 1; i < intNum; i++)
- {
- getbyte = getHello.DownByte(i);
- Mstream.Write(getbyte, 0, getbyte.Length);//寫到內(nèi)存中
- }
- Mstream.Position = 0;
- getbyte = new byte[Mstream.Length];
- Mstream.Read(getbyte, 0, getbyte.Length);//從內(nèi)存中讀到getbyte中
- Mstream.Close();
- //反序列化
- DataSet ds = KCDataFormatter.RetrieveDataSetDecompress(getbyte);
這里就得到了服務(wù)端返回的WCF DateSet.全部代碼已經(jīng)打包,vs2008中文版編譯通過!
【編輯推薦】