【问题标题】:exception handling for wcf servicewcf 服务的异常处理
【发布时间】:2011-12-10 03:56:46
【问题描述】:

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

【问题讨论】:

  • CommunicationException 的错误信息是什么意思,是否存在内部异常?
  • 嗨。用错误消息更新了我上面的帖子。谢谢

标签: wcf exception exception-handling


【解决方案1】:

这里的问题是之前的调用出现了错误,使通信通道处于失败状态。因此,在关闭之前无法使用。

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

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

可能是通道超时,处于故障状态。

        try
        {
              client.Subscribe();  
        }

        catch (Exception exception)
        {

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

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

【讨论】:

  • 嗨。谢谢您的回复。在尝试了您提供的代码后,单击连接按钮后,它会发送一次错误。在第二次点击之后,它给出了错误“无法访问已处置的对象。对象名称:'System.ServiceModel.Channels.ServiceChannel'。”
  • 因为我需要客户端变量在整个文档中都可用,所以我在程序开始时创建了一个变量,而不是每次尝试连接时都声明一个新变量。
  • 这就是你的问题所在。一旦“客户端变量”(服务通道)出现故障,它就不能再次使用。每次连接时都必须创建一个新实例。
【解决方案2】:

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

由于您需要在整个项目中都可以使用该变量,因此您可以在类的开头声明 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");

【讨论】:

    【解决方案3】:

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

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

    最好的问候。

    【讨论】:

    • 嗨。谢谢您的答复。通过再次重新创建客户端,我使用了以下代码 var client = new PostingContractClient();它给了我 PostingContractClient 的错误,它不包含接受 0 个参数的构造函数。不知道我应该把论点写成什么。
    • 我的意思是,您应该使用与以前相同的构造函数。在你的情况下new PostingContractClient(site);
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-13
    • 1970-01-01
    • 1970-01-01
    • 2011-03-19
    • 1970-01-01
    • 2014-11-22
    相关资源
    最近更新 更多