WCF Duplex:如何处理双工回调中的抛出异常

时间:2011-04-07 10:21:12

标签: wcf wcf-client wcf-callbacks

如何在WCF双工设置中处理客户端上的回调方法中抛出的异常?

目前,客户端似乎没有引发故障事件(除非我不正确地监控它?)但是使用客户端调用Ping()之后的任何事件都失败并显示CommunicationException:“通信对象System.ServiceModel。 Channels.ServiceChannel,因为已被中止而不能用于通信。“。

如何处理此问题并重新创建客户端等?我的第一个问题是如何找出它何时发生。其次,如何最好地处理它?<​​/ p>

我的服务和回调合同:

[ServiceContract(CallbackContract = typeof(ICallback), SessionMode = SessionMode.Required)]
public interface IService
{
    [OperationContract]
    bool Ping();
}

public interface ICallback
{
    [OperationContract(IsOneWay = true)]
    void Pong();
}

我的服务器实施:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Single)]
public class Service : IService
{
    public bool Ping()
    {
        var remoteMachine = OperationContext.Current.GetCallbackChannel<ICallback>();

        remoteMachine.Pong();
    }
}

我的客户端实施:

[CallbackBehavior(UseSynchronizationContext = false, ConcurrencyMode = ConcurrencyMode.Single)]
public class Client : ICallback
{
    public Client ()
    {
        var context = new InstanceContext(this);
        var proxy = new WcfDuplexProxy<IApplicationService>(context);

        (proxy as ICommunicationObject).Faulted += new EventHandler(proxy_Faulted);

        //First Ping will call the Pong callback. The exception is thrown
        proxy.ServiceChannel.Ping();
        //Second Ping call fails as the client is in Aborted state
        try
        {
            proxy.ServiceChannel.Ping();
        }
        catch (Exception)
        {
            //CommunicationException here 
            throw;
        }
    }
    void Pong()
    {
        throw new Exception();
    }

    //These event handlers never get called
    void proxy_Faulted(object sender, EventArgs e)
    {
        Console.WriteLine("client faulted proxy_Faulted");
    }
}

1 个答案:

答案 0 :(得分:1)

事实证明,你不能指望提出Faulted事件。因此,重新建立连接的最佳方法是在后续调用Ping()失败时执行此操作:

我会在这里保持代码简单:

public class Client : ICallback
{
    public Client ()
    {
        var context = new InstanceContext(this);
        var proxy = new WcfDuplexProxy<IApplicationService>(context);

        (proxy.ServiceChannel as ICommunicationObject).Faulted +=new EventHandler(ServiceChannel_Faulted);

        //First Ping will call the Pong callback. The exception is thrown
        proxy.ServiceChannel.Ping();
        //Second Ping call fails as the client is in Aborted state
        try
        {
            proxy.ServiceChannel.Ping();
        }
        catch (Exception)
        {
            //Re-establish the connection and try again
            proxy.Abort();
            proxy = new WcfDuplexProxy<IApplicationService>(context);
            proxy.ServiceChannel.Ping();
        }
    }
    /*
    [...The rest of the code is the same...]
    //*/
}

显然,在我的示例代码中,Exception将再次抛出,但我希望这对于让人们了解如何重新建立连接非常有用。