2012-10-19 28 views
5

我想在一個線程(在後臺)上打開一個代理,線程創建一個新的代理實例,調用該服務的一個方法並立即配置服務。在線程上啓動多個服務

所有這一切都發生在一個線程:

var background = new Thread(() => 
{ 
    var proxy = new AssignmentSvcProxy(new EndpointAddress(worker.Address));    

    try 
    { 
     proxy.Channel.StartWork(workload); 
     proxy.Dispose();     
    } 
    catch (EndpointNotFoundException ex) 
    { 
     logService.Error(ex);       
     proxy.Dispose(); 
     proxy = null; 
    } 
    catch (CommunicationException ex) 
    { 
     logService.Error(ex); 
     proxy.Dispose(); 
     proxy = null; 
    } 
    catch (TimeoutException ex) 
    { 
     logService.Error(ex);      
     proxy.Dispose(); 
     proxy = null; 
    } 
    catch (Exception ex) 
    { 
     logService.Error(ex);      
     proxy.Dispose(); 
     proxy = null; 
    }     

}) { IsBackground = true }; 

background.Start(); 

我一直看到,即使我已經超時設置爲最大值爲CloseTimeout,OpenTimeout,ReceiveTimeout,發生的SendTimeout間歇超時問題。

我只是想確保明智的設計這不是一個問題,即打開一個線程上的服務和處理它?

編輯:

代理內部建立與上爲每個線程不同的端點定義綁定的信道。

+0

這是一個有點混亂,你說話「服務」的,我所期待的「代理」(甚至「客戶」),例如「線程打開服務」應該是「線程爲我的服務打開代理」,對嗎? – Jeroen

+0

對不起,我只是更新了問題,所以基本上我的服務已經打開,但是代理只是調用proxy.Channel.StartWork(工作負載);那個特定的服務(已經是自己託管的) - 有意義嗎? –

+0

你可能想在你的try-catch子句中加上'finally'。最終即使拋出異常也會執行代碼。關於你的問題,我不確定。我也相信把你的綁定傳遞給構造函數是明智的。這可能是超時異常的原因。 –

回答

6

我認爲問題可能在於您沒有正確關閉代理服務器。如果你有很多線程打到服務器上,並且他們並不都清理完畢,你可能會在這些連接上出現超時。

處理對於關閉連接並不理想。點擊此處瞭解詳情:Disposing proxies

的理想模式使用如下:

try 
{ 
    proxy.Close(); 
} 
catch (Exception ex) 
{ 
    proxy.Abort(); 
} 
finally 
{ 
    proxy = null; 
} 

您嘗試關閉連接,如果失敗,則中止所有連接。如果發生異常,Dispose不會中止。

因此,我將重構像這樣:

var background = new Thread(() => 
{ 
    var proxy = new AssignmentSvcProxy(new EndpointAddress(worker.Address));    

    try 
    { 
     proxy.Channel.StartWork(workload); 
    } 
    catch (Exception ex) 
    { 
     // You aren't doing anything special with your specific exception types 
     logService.Error(ex);      
    }     
    finally 
    { 
     try 
     { 
      proxy.Close(); 
     } 
     catch (Exception ex) 
     { 
      proxy.Abort(); 
     } 
     finally 
     { 
      proxy = null; 
     } 
    } 

}) { IsBackground = true }; 

background.Start(); 
+1

這工作。但是,WCF代理是線程安全的(併發調用被序列化)。由於創建代理並打開與服務器的新連接是一項昂貴的操作,因此通常在線程間重用代理。 –

+0

我同意,這就是爲什麼他應該理想地有一個重試機制,以防因任何原因導致連接失敗。故障處理中的這種模式將確保在強制創建新連接之前清除舊連接。 – Bardia