wcf服务的异常处理

时间:2011-12-10 03:56:46

标签: wcf exception exception-handling

我目前正在开发一个wcf发布订阅服务。在我的Windows窗体应用程序中,我有一个尝试订阅该服务的“连接”按钮。代码如下

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服务尚未启动”之前加载一段时间。 ,之后我激活了服务,单击“连接”按钮向我显示第二个错误,即使我的服务处于打开状态,也是CommunicationException。

知道如何解决这个问题吗?

错误的错误消息

  

通信对象System.ServiceModel.Channels.ServiceChannel不能用于通信,因为它处于Faulted状态。

3 个答案:

答案 0 :(得分:3)

这里的问题是前一个呼叫出错并使通信信道处于故障状态。因此在关闭之前不能使用它。

您需要捕获任何错误并清理并在故障状态下进行通道。

这是我们使用的一些标准代码,在您的情况下,您可能不想关闭频道。

可能是因为频道已经超时,所以频道处于故障状态。

        try
        {
              client.Subscribe();  
        }

        catch (Exception exception)
        {

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

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

答案 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();

最好的问候。

答案 2 :(得分:1)

不确定这是否是您想要的,但从您的问题中我可以理解,这似乎就是您所需要的:

由于您需要变量在整个项目中可用,因此您可以在类的开头声明InstanceContext和Client。

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");