2009-07-20 2 views

答えて

4

私は、このモデルで幸運を持っていた:あなたは正しい一般的なアイデアを持っている

Dim service As New MyService() 
Dim closed As Boolean = False 
Try 
    service.Open() 
    If Not service.State = ServiceModel.CommunicationState.Opened Then 
     ''Handle a not-opened state here 
    End If 
    service.MyMethod() 
    service.Close() 
    closed = true 
Catch ex As Exception 
    ''Handle errors here 
Finally 
    If Not closed Then 
     service.Abort() 
    End If 
End Try 
service = Nothing 
2

。私は以下の拡張メソッドを使用して、繰り返しコードの行を最小限に保ちました。この拡張メソッドを使用してコードの

public static class ICommunicationObjectExtensions 
{  
    public static void SafelyCloseConnection(this ICommunicationObject objectToClose) 
    { 
     bool success = false; 

     try 
     { 
     objectToClose.Close(); 
     success = true; 
     } 
     finally 
     { 
     if (!success) 
     { 
      objectToClose.Abort(); 
     } 
     } 
    } 
} 

例:もちろん

HelloWorldServiceClient client = new HelloWorldServiceClient(); 
HelloWorldDataContract dc = new HelloWorldDataContract(); 

try 
{ 
    client.Open(); 
    dc = client.SayHello(); 
} // Add catch blocks here for anything you want to handle. 
finally 
{ 
    client.SafelyCloseConnection(); 
} 

これは、C#ですが、私はそれはまだ助けになるべきだと思います。

15

参照Indisposable:WCFガッチャ#1 *、彼は便利なラッパーメソッドを思い付く:

public delegate void UseServiceDelegate<T>(T proxy); 

public static class Service<T> 
{ 
    public static ChannelFactory<T> _channelFactory = new ChannelFactory<T>(""); 

    public static void Use(UseServiceDelegate<T> codeBlock) 
    { 
     var proxy = (IClientChannel)_channelFactory.CreateChannel(); 
     var success = false; 
     try 
     { 
      codeBlock((T)proxy); 
      proxy.Close(); 
      success = true; 
     } 
     finally 
     { 
      if (!success) 
      { 
       proxy.Abort(); 
      } 
     } 
    } 
} 

使用法:

Service<IOrderService>.Use(
    orderService => 
     { 
      orderService.PlaceOrder(request); 
     }); 

*悪質なように見えるように除去リンク。あなたはクライアント側のキャッシュを使用する場合は、式ツリーを使用して検討するかもしれない

+0

ことを、私はあなたのソリューションを好きですが、あなたは1を持っていますDependency Injectionで使用できます。サービスは依存関係であるため、私はそれに対してテストを実行したくありません。 –

+0

私の解決策ではありません。いずれにしても、 'Service 'を非静的にして、 'ChannelFactory 'または 'IClientChannel'を注入することができます。 –

0

http://thegrenade.blogspot.com/2009/07/using-expression-trees-for-more-elegant.htmlを参照してください):

private static TEntity GetItem<TProxy, TEntity, TIdentity>(Expression<Func<TProxy, TIdentity, TEntity>> expression, TProxy proxy, TIdentity id) 
    where TEntity : class 
    where TProxy : ICommunicationObject 
{ 
    TEntity item = Cache.GetItem<TEntity, TIdentity>(id); 
    if (item == null) 
    { 
     try 
     { 
      var originalDelegate = expression.Compile(); 
      item = originalDelegate.Invoke(proxy, id); 
     } 
     finally 
     { 
      try{ proxy.Close(); } 
      finally { proxy.Abort(); } 
     } 
     Cache.AddItem<TEntity, TIdentity>(item); 
    } 
    return item; 
} 

使用法:

Product p = GetItem((client, identifier) => client.GetProduct(identifier), new CatalogServiceClient(), 123); 
+0

ロブ、あなたの答えがこの質問にどのように当てはまるのか分かりません。 –

+0

おそらく、私が与えたメソッドの例は、汎用サービス呼び出しラッパーにはあまりにも限定的です。実際には、複数のパラメータを使用するサービスメソッドのメソッドオーバーロードが必要です。この例ではその詳細には触れません。しかし、多くのWCFソリューションには、idパラメータを使用した取得に応答して異なるタイプを返す非常に類似したメソッドのグループが含まれています。そして、あなたは私の最終的なブロックが中断されたtry/finallyを中止していることが間違っています。 – grenade

+0

質問をもう一度読む必要があるかもしれないと思います。あなたの答えは決して質問に答えません。 –

関連する問題