2011-12-10 223 views
1

我目前正在開發一個wcf發佈訂閱服務。在我的Windows窗體應用程序中,我有一個連接按鈕,試圖訂閱服務。代碼如下wcf服務的異常處理

WSDualHttpBinding binding = (WSDualHttpBinding)client.Endpoint.Binding; 
string clientcallbackaddress = binding.ClientBaseAddress.AbsoluteUri; 
clientcallbackaddress += Guid.NewGuid().ToString(); 
binding.ClientBaseAddress = new Uri(clientcallbackaddress); 

InstanceContext site = new InstanceContext(null, new mainForm(backgroundFormObject)); 
PostingContractClient client = new PostingContractClient(site); 

client.Subscribe(); 
MessageBox.Show("Service has been connected!", "Connected"); 

作爲例外處理,這是我做了什麼,

try 
{ 
    //refer to codes above 
} 
catch (EndpointNotFoundException) 
{ 
    MessageBox.Show("WCF Service has not been started.", "Error"); 
} 
catch (CommunicationException) 
{ 
    MessageBox.Show("Error"); 
} 

如果我的服務沒有被激活,在點擊連接按鈕,它會加載一段時間在發送第一個錯誤之前,「WCF服務尚未啓動。」 ,之後我激活服務,點擊Connect按鈕會顯示第二個錯誤,即使我的服務處於打開狀態,也是CommunicationException。

任何想法如何解決這一問題?

用於誤差

的通信對象,System.ServiceModel.Channels.ServiceChannel,該錯誤消息不能被用於通信,因爲它是處於故障狀態。

+0

什麼是對的CommunicationException錯誤消息說,是有一個內部異常? – Tim

+0

嗨。用錯誤信息更新了我的帖子。謝謝 – Thomas

回答

1

不知道這是否是你想要的,但我可以從你的問題理解這似乎是你所需要的:

既然你需要的變量是在整個項目中可用,你可以聲明InstanceContext和客戶端。

InstanceContext site; 
PostingContractClient client; 

在Form_Load方法遵循,

site = new InstanceContext(null, new mainForm(backgroundFormObject)); 
client = new PostingContractClient(site); 

終於在 「連接」 按鈕,

 try 
     { 
      site = new InstanceContext(null, new mainForm(backgroundFormObject)); 
      var client = new PostingContractClient(site); 

      WSDualHttpBinding binding = (WSDualHttpBinding)client.Endpoint.Binding; 
      string clientcallbackaddress = binding.ClientBaseAddress.AbsoluteUri; 
      clientcallbackaddress += Guid.NewGuid().ToString(); 
      binding.ClientBaseAddress = new Uri(clientcallbackaddress); 

      client.Subscribe(); 
      MessageBox.Show("Service has been connected!", "Connected"); 
     } 
     catch (EndpointNotFoundException) 
     { 
      if (client != null) 
      { 
       MessageBox.Show("WCF Service has not been started. Please try to manually connect again after the service has been started.", "Error"); 
3

這裏的問題是前面的調用發生了錯誤並且使通信通道處於失敗狀態。因此它在關閉之前不能使用。

您需要捕獲任何錯誤並清理並處於故障狀態。

這是我們使用的一些標準代碼,在您的情況下您可能不想關閉該頻道。

也許該通道由於超時而處於故障狀態。

 try 
     { 
       client.Subscribe(); 
     } 

     catch (Exception exception) 
     { 

      if (client != null) 
      { 
       client.Abort(); 
      } 
      throw; 
     } 

     finally 
     { 
      if (client != null) 
      { 
       client.Close(); 
      } 
     } 
+0

嗨。謝謝您的回覆。在嘗試完您輸入的代碼後,點擊連接按鈕後,它會發送一次錯誤。在第二次點擊之後,它給出錯誤「無法訪問處置的對象。」 對象名稱:'System.ServiceModel.Channels.ServiceChannel'。「 – Thomas

+0

因爲我需要客戶端變量在整個文檔中都可用,所以我在程序開始時創建了一個變量,而不是每次嘗試連接時都聲明一個新變量。 – Thomas

+1

這就是你的問題所在。一旦「客戶端變量」(服務通道)發生故障,它就不能再次使用。每次連接時都必須創建一個新實例。 –

1

我是一個有點困惑上面的代碼,並試圖解釋在註釋:

// The client seems to be initialized by that time 
WSDualHttpBinding binding = (WSDualHttpBinding)client.Endpoint.Binding; 

... 

// The client is initialized again 
PostingContractClient client = new PostingContractClient(site); 

無論如何,從錯誤中,您已發佈,似乎您試圖使用相同的對象兩個後續調用,如:

var client = new Client(); 
client.Subscribe(); // you get an exception here 
client.Subscribe(); // channel is faulted, as you got an exception accessing it the first time 

我沒有添加WCF服務引用工作了,我不知道實現細節。但隨着裝配分享了很多的工作,我會建議嘗試再次創建Client

var client = new Client(); 
client.Subscribe(); // you get an exception here 

client = new Client(); // I hope, another Channel is created, when calling the constructor. 
client.Subscribe(); 

最好的問候。

+0

嗨。感謝您的答覆。通過重新創建客戶端,我使用了以下代碼var client = new PostingContractClient();它給我PostingContractClient的錯誤不包含一個構造函數,該構造函數接受0個參數。不知道我把參數作爲什麼。 – Thomas

+0

我的意思是,你應該使用與以前相同的構造函數。在你的情況'新PostingContractClient(網站);' –