2010-11-23 46 views
2

我試圖找到一個優雅的方式來重試WCF渠道處於故障狀態時的操作。當第一次調用發生故障狀態異常時,我嘗試使用Policy Injection AB重新連接並重試該操作,但是PolicyInjection.Wrap方法似乎不喜歡包裝TransparentProxy對象(從ChannelFactory.CreateChannel返回的代理)。WCF操作時的重試機制調用當渠道處於fautled狀態

是否有任何其他機制我可以嘗試或如何嘗試讓PIAB解決方案正常工作 - 任何鏈接,示例等將不勝感激。

下面是我用這是錯誤的代碼:
var channelFactory = new ChannelFactory(endpointConfigurationName);
var proxy = channelFactory.CreateChannel(...);
proxy = PolicyInjection.Wrap<IService>(proxy);

謝謝。

回答

0

非常感謝您的回覆。我最終做的是創建一個裝飾器類型類,它實現了我的服務的接口,然後它包裝了由ChannelFactory生成的透明代理。然後,我可以使用策略注入應用程序塊在其上創建一個層,將代碼注入每個將嘗試操作的操作調用中,並且如果發生CommunicationObjectFaultedException異常,則會中止通道,重新創建它並重試操作。它現在工作的很好 - 雖然效果很好,但唯一的缺點是包裝類提到必須實施每個服務操作,但這是我可以使用PIAB的唯一方式,因爲這對我來說是有意義的,以防萬一我找到了在未來的方式,很容易改變只使用接口。

3

我寧願使用回調函數,這樣的事情:

private SomeServiceClient proxy; 

    //This method invokes a service method and recreates the proxy if it's in a faulted state 
    private void TryInvoke(Action<SomeServiceClient> action) 
    { 
     try 
     { 
      action(this.proxy); 
     } 
     catch (FaultException fe) 
     { 
      if (proxy.State == CommunicationState.Faulted) 
      { 
       this.proxy.Abort(); 
       this.proxy = new SomeServiceClient(); 
       //Probably, there is a better way than recursion 
       TryInvoke(action); 
      } 
     } 
    } 

    //Any real method 
    private void Connect(Action<UserModel> callback) 
    { 
     TryInvoke(sc => callback(sc.Connect())); 
    } 

而且在你的代碼,你應該調用

ServiceProxy.Instance.Connect(user => MessageBox.Show(user.Name)); 

代替

var user = ServiceProxy.Instance.Connect(); 
MessageBox.Show(user.Name); 

雖然我的代碼使用代理類的方法,您可以使用Channels編寫類似的代碼。

+0

謝謝你的回答 - 非常感謝。我對這個解決方案的一個擔憂是,我需要對於我有的100到200個奇怪的服務調用,確保每個服務調用的調用都被包裝在一個ServiceProxy.Instance.TryInvoke中,並且添加到這個調用中,一個維護夢魘,確保任何額外的服務調用也被包裝 - 除了使用策略注入AppBlock(或其他AOP類型的框架) - 除非我錯過了某些東西,否則我看不到任何其他方式來解決此問題。 – CraigM 2010-11-24 13:08:27

相關問題