2011-12-10 86 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(网站);' –