What is the best workaround for the WCF client `using` block issue?

前端 未结 26 2105
余生分开走
余生分开走 2020-11-22 00:03

I like instantiating my WCF service clients within a using block as it\'s pretty much the standard way to use resources that implement IDisposable:

26条回答
  •  野的像风
    2020-11-22 00:25

    Based on answers by Marc Gravell, MichaelGG, and Matt Davis, our developers came up with the following:

    public static class UsingServiceClient
    {
        public static void Do(TClient client, Action execute)
            where TClient : class, ICommunicationObject
        {
            try
            {
                execute(client);
            }
            finally
            {
                client.DisposeSafely();
            }
        }
    
        public static void DisposeSafely(this ICommunicationObject client)
        {
            if (client == null)
            {
                return;
            }
    
            bool success = false;
    
            try
            {
                if (client.State != CommunicationState.Faulted)
                {
                    client.Close();
                    success = true;
                }
            }
            finally
            {
                if (!success)
                {
                    client.Abort();
                }
            }
        }
    }
    

    Example of use:

    string result = string.Empty;
    
    UsingServiceClient.Do(
        new MyServiceClient(),
        client =>
        result = client.GetServiceResult(parameters));
    

    It's as close to the "using" syntax as possible, you don't have to return a dummy value when calling a void method, and you can make multiple calls to the service (and return multiple values) without having to use tuples.

    Also, you can use this with ClientBase descendants instead of ChannelFactory if desired.

    The extension method is exposed if a developer wants to manually dispose of a proxy/channel instead.

提交回复
热议问题