wcf服务的异常处理

wcf服务的异常处理,wcf,exception,exception-handling,Wcf,Exception,Exception Handling,我目前正在开发一个wcf发布-订阅服务。在我的windows窗体应用程序上,我有一个尝试订阅服务的连接按钮。代码如下 WSDualHttpBinding binding = (WSDualHttpBinding)client.Endpoint.Binding; string clientcallbackaddress = binding.ClientBaseAddress.AbsoluteUri; clientcallbackaddress += Guid.NewGuid().ToString(

我目前正在开发一个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无法用于通信,因为它处于故障状态


这里的问题是,上一次调用出现错误,使通信通道处于失败状态。因此,只有在关闭后才能使用

您需要捕获任何错误,并清理处于故障状态的通道

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

这可能是因为通道处于故障状态,因为它具有timedout

        try
        {
              client.Subscribe();  
        }

        catch (Exception exception)
        {

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

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

这里的问题是,上一次调用出现错误,使通信通道处于失败状态。因此,只有在关闭后才能使用

您需要捕获任何错误,并清理处于故障状态的通道

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

这可能是因为通道处于故障状态,因为它具有timedout

        try
        {
              client.Subscribe();  
        }

        catch (Exception exception)
        {

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

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

我对上面的代码有点困惑,试着在注释中解释一下:

// 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服务作为参考方面做得不多,也不知道实现细节。但是在大量使用程序集共享时,我建议再次尝试创建
客户端

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

致以最诚挚的问候。

我对上面的代码有点困惑,请尝试在评论中解释:

// 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服务作为参考方面做得不多,也不知道实现细节。但是在大量使用程序集共享时,我建议再次尝试创建
客户端

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

致以最诚挚的问候。

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

因为您需要变量在整个项目中都可用,所以可以在类的开头声明InstanceContext和客户机

InstanceContext site;
PostingContractClient client;
按照“形式荷载法”中的

site = new InstanceContext(null, new mainForm(backgroundFormObject));
client = new PostingContractClient(site);
最后在“连接”按钮中


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

因为您需要变量在整个项目中都可用,所以可以在类的开头声明InstanceContext和客户机

InstanceContext site;
PostingContractClient client;
按照“形式荷载法”中的

site = new InstanceContext(null, new mainForm(backgroundFormObject));
client = new PostingContractClient(site);
最后在“连接”按钮中


CommunicationException的错误消息说了什么,是否存在内部异常?您好。用错误消息更新了我上面的帖子。谢谢CommunicationException的错误消息说什么,是否存在内部异常?嗨。用错误消息更新了我上面的帖子。谢谢。谢谢你的回复。在尝试您提供的代码后,单击connect按钮,它会发送一次错误。之后,在第二次单击时,会出现错误“无法访问已处理的对象。对象名称:'System.ServiceModel.Channels.ServiceChannel.”,因为我需要客户端变量在整个文档中都可用,我在程序开始时创建了一个变量,而不是每次尝试连接时都声明一个新变量。这就是问题所在。一旦“客户端变量”(服务通道)出现故障,就不能再次使用。每次连接时都必须创建一个新实例。hi。谢谢你的回复。在尝试您提供的代码后,单击connect按钮,它会发送一次错误。之后,在第二次单击时,会出现错误“无法访问已处理的对象。对象名称:'System.ServiceModel.Channels.ServiceChannel.”,因为我需要客户端变量在整个文档中都可用,我在程序开始时创建了一个变量,而不是每次尝试连接时都声明一个新变量。这就是问题所在。一旦“客户端变量”(服务通道)出现故障,就不能再次使用。每次连接时都必须创建一个新实例。hi。谢谢你的回复。通过重新创建客户机,我使用了以下代码var client=new PostingContractClient();它给我的错误是PostingContractClient不包含接受0个参数的构造函数。我不确定我应该把这些参数当作什么。我的意思是,你应该像以前一样使用相同的构造函数。在您的情况下,
新的PostingContractClient(站点)你好。谢谢你的回复。通过重新创建客户机,我使用了以下代码var client=new PostingContractClient();它给我的错误是PostingContractClient不包含接受0个参数的构造函数。我不确定我应该把这些参数当作什么。我的意思是,你应该像以前一样使用相同的构造函数。在您的情况下,
新的PostingContractClient(站点)