最近有個項目,涉及到客戶自有的系統及公司開發的系統,兩個系統資料存在不一致的情況,需要資料同步。客戶自有的系統提供資源資訊服務介面,公司部署的系統調用該介面將資料同步過來。
客戶給的是webservice介面,調用了一下,調用一次大概是2秒的樣子,如果算上解析記錄,差不多要2.4秒。由於資料量比較大,自然想到了平行處理。在.net framework4.0 中,提供了便捷的平行處理,不用自己再寫線程了。
周五同事寫了部分程式,webservice的請求總是發不出去,由於當時還在處理其他的項目,沒認真看他寫的代碼。今天重新整理下,寫了個大體架構,只需將擷取的資料同步到資料庫,即可。代碼如下:
View Code
/// <summary>
/// 同步資料對象。用於從webservice中擷取資料後同步
/// </summary>
public class WebServiceClient{
private const string WEBSERVICE_URL = "http://host/axis2/services/BookBeanServer";
public static string LastError = string.Empty;
public WebServiceClient() { }
/// <summary>
/// 處理單本資源。為調用處使用平行處理,此處只處理單本資源。
/// </summary>
/// <param name="metaId"></param>
/// <returns></returns>
public bool Process(string metaId) {
var result = new Book();
try {
result.InitializeFrom(this.GetBookOrignalXmlFromWebService(metaId));
}
catch (XmlException ex) {
LastError = ex.Message;
return false;
}
return this.SynData(result);
}
private string GetBookOrignalXmlFromWebService(string metaId) {
MyWebServiceReference.BookBeanServerPortTypeClient client = new MyWebServiceReference.BookBeanServerPortTypeClient(
new WSHttpBinding(SecurityMode.None),
new EndpointAddress(WEBSERVICE_URL)
);
object obj = client.getBook(new string[] { metaId });
XmlNode[] nodes = (XmlNode[])obj;
return nodes.Length > 0 ? nodes[0].InnerXml : string.Empty;
}
private bool SynData(Book Book) {
//TODO:同步資料
return true;
}
}
WebServiceClient表示單本資源處理類,其職責是調用WebService,將擷取的資料同步到資料庫。
由於涉及到的資料量比較大,在調用出使用平行處理。.Net framework4.0中,提供了平行處理方案,在平行處理方面,更推薦使用其提供的Parallel類,與ThreadPool相比,減少了線程開銷。
調用處代碼如下:
1 Parallel.ForEach<string>(
2 GetMetaIds(),
3 metaid => {
4 WebServiceClient client = new WebServiceClient();
5 var temp = Task.Factory.StartNew(() => { return client.Process(metaid); });
6 temp.ContinueWith(tmp => {
7 //TODO:處理同步處理的結果
8 Console.WriteLine(tmp.Result ? "ok" : "f");
9 });
10 }
11 );
其中GetMetaIds()函數返回IList<string>資料,儲存調用的WebService的參數集合。
在Visual Studio中,在建立的項目中添加web service引用,會自動產生訪問代理類。此處為webservice引用建立了MyWebServiceReference的命名空間。
網上關於C# WebService的文章很多,搜尋出來的多是用C#寫的Producer和Consumer做為示範,與單獨寫Consumer還是有區別的。與Consumer在同一個solution中的Producer,添加WebService引用到Consumer工程後,能通過代理直接存取到,但是,如果添加另外的Consumer,產生的代理如果直接調用會讓人有些迷惑,不知道怎麼調用。