2011-04-07 23 views
1

如何在WCF雙工設置中處理在客戶端的回調方法中拋出的異常?WCF雙工:如何處理在雙工中拋出的異常回調

目前,客戶端似乎沒有引發故障事件(除非我對它進行了不正確的監控?),但是隨後使用客戶端調用Ping()失敗並出現CommunicationException:「通信對象System.ServiceModel .Channels.ServiceChannel不能用於通信,因爲它已被中止。「

我該如何處理這個問題並重新創建客戶端等?我的第一個問題是如何找出它何時發生。其次,如何最好地處理它呢?

我的服務和回調合同:

[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

事實證明,你不能指望該故障事件待提高。因此,要重新建立連接的最佳方式是什麼時候中國平安()後續調用失敗做到這一點:

我會保持代碼的簡潔這裏:

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...] 
    //*/ 
} 

顯然,在我的例子代碼,異常將再次拋出,但我希望這有助於讓人們知道如何重新建立連接。