代码之家  ›  专栏  ›  技术社区  ›  Larry Watanabe

service.close()与service.abort()-wcf示例

  •  8
  • Larry Watanabe  · 技术社区  · 16 年前

    在一个WCF教程中,我看到了以下示例代码:

    Dim service as ...(a WCF service )
    
    try
    
       ..
    
       service.close()
    
    catch ex as Exception()
      ... 
    
       service.abort()
    
    end try
    

    这是确保资源(即连接)即使在错误情况下也被释放的正确方法吗?

    4 回复  |  直到 11 年前
        1
  •  4
  •   Chris Porter    16 年前

    我对这个模型很幸运:

    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
  •  15
  •   ChrisF    11 年前

    见不可分辨:wcf gotcha 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);
            });
    

    *链接被删除,因为它似乎是恶意的。

        3
  •  2
  •   Daniel Auger    16 年前

    你的总体想法是正确的。我使用了下面的扩展方法来将重复代码的行保持在最低限度。

    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,但我认为这仍然有帮助。

        4
  •  0
  •   grenade    16 年前

    如果使用客户端缓存,则可以考虑使用表达式树(请参见 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);