簡體   English   中英

c# wcf - 在代理 class 上調用 open() 時引發異常

[英]c# wcf - exception thrown when calling open() on proxy class

我有以下問題,基本上我有一個 WCF 服務在小型測試中運行良好。 但是,當我嘗試進行批處理/負載測試時,當在代理 class 上調用 open() 方法時,會收到InvalidOperationException消息:

“通訊 object,System.ServiceModel.Channels.ServiceChannel,在打開的 state 中無法修改。”

我搜索了谷歌,但找不到其他人真正引用此異常消息。

我想診斷可能需要有關服務的一些進一步信息 - 當服務通過其公開的方法之一接收數據時,它基本上執行一些處理並將數據路由到與數據關聯的服務(不同的數據將導致不同的路由)。 為了確保服務盡快運行,數據的接收、處理和路由的每個周期都由線程池中的單獨線程處理。 這可能是一個線程調用proxyClass.Open()而另一個線程已經在使用它而引起的問題嗎? 如果確實是這個問題, lock塊會消除這個問題嗎?

謝謝大家, - 我在這個項目上工作太久了,終於想看看它的背面 - 但這似乎是最后一個絆腳石,所以非常感謝任何幫助:-)

==================================================== ========================

感謝您強調我不應該對 WCF 代理類using構造。 然而,MSDN 文章並不是有史以來寫得最清楚的文獻,所以一個簡單的問題:我應該使用這樣的代理嗎:

try
{
    client = new proxy.DataConnectorServiceClient();
    client.Open();
    //do work
    client.Close();
 }
 .................. //catch more specific exceptions
 catch(Exception e)
 {
    client.Abort();
 }

我假設您使用的是 .NET 3.5 或更高版本。 In .NET 3.5, the WCF ClientBase'1 class (base class for generated client proxies) was updated to use cached ChannelFactories/Channels. 因此,除非您使用禁用緩存的客戶端使用/創建策略之一(接收綁定 object 的客戶端構造函數,或在創建后備通道之前訪問某些特定屬性之一),即使您正在創建一個新的客戶端實例,它很可能仍在使用相同的通道。 換句話說,在調用.Open() 之前,請始終確保您正在檢查.Created 狀態。

你是如何使用代理的? 為每個調用創建新的代理 object。 添加一些關於如何使用代理的代碼。

使用代理的理想方式是為每個調用創建新代理並在完成后處理它。 您正在為錯誤的打開代理調用 proxy.open() 。 它應該只調用一次。

最后嘗試使用類似下面的東西,因為 wcf 不會處理失敗的代理並且它會堆積起來。 不確定它是否會有所幫助,但可以試一試。

if (proxy.State == CommunicationState.Faulted)
{
    proxy.Abort();
}
else
{
    try
    {
        proxy.Close();
    }
    catch
    {
        proxy.Abort();
    }
}

為什么要這樣做? http://msdn.microsoft.com/en-us/library/aa355056.aspx

您在上面發布的代碼可以工作,但您總是會吃異常。 因此,在單獨的捕獲中處理與 wcf 相關的異常,並且您使用 Excelion 的通用捕獲將中止然后拋出異常。

try
{
    ...
    client.Close();
}
catch (CommunicationException e)
{
    ...
    client.Abort();
}
catch (TimeoutException e)
{
    ...
    client.Abort();
}
catch (Exception e)
{
    ...
    client.Abort();
    throw;
}

此外,如果您仍然想使用方便的 using 語句,那么您可以覆蓋代理中的 dispose 方法,並在出現 wcf 錯誤的情況下使用 abort 方法進行處理。

並且不需要 call.Open() 因為它會在第一次調用時打開。

聽起來您確實在同一個 object 上多次調用了 Open()。

前段時間我們遇到了和你一樣的障礙。

using 語句的問題在於,如果您遇到錯誤的 state,它仍會嘗試在塊的末尾關閉。 另一個對我們至關重要的考慮因素是每次創建代理的成本。

我們從這些博客文章中學到了很多:

http://blogs.msdn.com/wenlong/archive/2007/10/26/best-practice-always-open-wcf-client-proxy-explicitly-when-it-is-shared.aspx

http://blogs.msdn.com/wenlong/archive/2007/10/27/performance-improvement-of-wcf-client-proxy-creation-and-best-practices.aspx

希望它也會對您有所幫助。

干杯,瓦格納。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM