2012-02-06 160 views
3

我目前正在看一些基本上從文件中逐行讀取數據的代碼,並在每一行的WCF客戶端上調用適當的方法。我的代碼的問題是,新的客戶端爲每個操作即創建:調用WCF客戶端上的多個操作

function CallSomeOp(line) 
{ 
    using (var client = new Client() 
    { 
     client.SomeOp(line); 
    } 
} 

這似乎使客戶端關閉連接並重新打開該文件中的每一行一個新的這似乎是一筆大開銷。我想這樣做的是移動的功能外,進入初始化客戶端的創建,使多個操作被稱爲一個客戶端上,即:

using (var client = new Client()) 
{ 
    for(var line in lines) 
    { 
     CallSomeOp(line, client); 
    } 
} 

但我不知道這是確定或不。在客戶端調用多個操作時是否存在一些問題,即最終是否會耗盡內存或某些內容?

回答

2

操作通常是無狀態的,因此這是預期的行爲。但您可以更改InstanceContextMode。這決定了是否每個調用都創建一個新的實例,或者是否有單個實例。問題是,如果你?就像我說的那樣,一個電話通常是無國籍的。只有一個實例也不能很好地擴展。我建議保持InstanceContextMode爲PerCall,這樣,每次調用Web服務器創建一個實例,我不會擔心太多的開銷。如果開銷真的成爲問題,也許服務不是你需要的。

然後是ConcurrencyMode它允許您指定多個要創建的線程。

就客戶而言,您無需在每次調用操作時重新創建它。或者,如果客戶端和服務器都知道合同,則還可以查看ChannelFactoryThis answer提供了一些細節。

+0

感謝您的回答,我做了一個實驗與探查和使用單個實例減少運行時間從58秒到25左右。我不太瞭解WCF,但這似乎是一個快速勝利。 – avid 2012-02-06 11:56:37

+0

你可以發佈一些你的服務代碼嗎?它有什麼作用?請注意,單個實例可能導致多個調用發生縮放問題。 – diggingforfire 2012-02-06 11:57:53

+0

我無法發佈該服務的代碼,我不完全確定它做了什麼!它應該只是採取一些數據,並把它放在某個地方。使用客戶端的申請人是單線程的。 – avid 2012-02-06 12:05:02

2

這絕對即使that's been improved in later versions重用多次調用WCF客戶端,因爲的確有在創造它的新實例成本,是個好主意。

最重要的事情要注意重複使用WCF客戶端的時候,雖然是,如果一個服務操作失敗,整個客戶端將被放置在一個faulted state不再能夠使用

您必須在客戶端代碼中考慮到這一點。根據您的要求,處理這種情況的一種方式可能是重新創建客戶端代理失敗的情況下,繼續處理輸入,如本例所示:

var client = new ServiceClient(); 

foreach (var line in lines) 
{ 
    try 
    { 
     client.DoSomething(line); 
    } 
    catch 
    { 
     client.Abort(); 
     client = new ServiceClient() 
    } 
} 

注意,你可能還需要跟蹤服務呼叫失敗的次數以及與什麼類型的異常有關,因爲在某些情況下,會完全中止操作而不是繼續嘗試,例如當遠程服務不可達時。

+0

謝謝你,這是很好的知道。 – avid 2012-02-06 12:03:28