1

在我的应用程序中,我发现有时 WCF 调用/通道的 Close() 会引发错误。我对这个主题做了一些研究,并在互联网上借了一些代码让我开始。

现在,我想知道这是正确的方法吗?或者我应该改进解决方案还是实施完全不同的东西?

通用类/静态类:

public class SafeProxy<Service> : IDisposable where Service : ICommunicationObject
{
    private readonly Service _proxy;
    public SafeProxy(Service s)
    {
        _proxy = s;
    }
    public Service Proxy
    {
        get { return _proxy; }
    }

    public void Dispose()
    {
        if (_proxy != null)
            _proxy.SafeClose();
    }        
}

public static class Safeclose
{
    public static void SafeClose(this ICommunicationObject proxy)
    {
        try
        {
            proxy.Close();
        }
        catch
        {
            proxy.Abort();
        }
    }
}

这就是我调用 WCF 的方式:

(WCFReference 是指向 WCF 服务地址的服务引用)

using (var Client = new SafeProxy<WCFReference.ServiceClient>(new WCFReference.ServiceClient()))
{
    Client.Proxy.Operation(info);                        
}
4

1 回答 1

3

这是我用来安全地与客户端的 WCF 服务交互的快速小扩展方法:

/// <summary>
/// Helper class for WCF clients.
/// </summary>
internal static class WcfClientUtils
{
    /// <summary>
    /// Executes a method on the specified WCF client.
    /// </summary>
    /// <typeparam name="T">The type of the WCF client.</typeparam>
    /// <typeparam name="TU">The return type of the method.</typeparam>
    /// <param name="client">The WCF client.</param>
    /// <param name="action">The method to execute.</param>
    /// <returns>A value from the executed method.</returns>
    /// <exception cref="CommunicationException">A WCF communication exception occurred.</exception>
    /// <exception cref="TimeoutException">A WCF timeout exception occurred.</exception>
    /// <exception cref="Exception">Another exception type occurred.</exception>
    public static TU Execute<T, TU>(this T client, Func<T, TU> action) where T : class, ICommunicationObject
    {
        if ((client == null) || (action == null))
        {
            return default(TU);
        }

        try
        {
            return action(client);
        }
        catch (CommunicationException)
        {
            client.Abort();
            throw;
        }
        catch (TimeoutException)
        {
            client.Abort();
            throw;
        }
        catch
        {
            if (client.State == CommunicationState.Faulted)
            {
                client.Abort();
            }

            throw;
        }
        finally
        {
            try
            {
                if (client.State != CommunicationState.Faulted)
                {
                    client.Close();
                }
            }
            catch
            {
                client.Abort();
            }
        }
    }
}

我这样称呼它:

var result = new WCFReference.ServiceClient().Execute(client => client.Operation(info));
于 2013-08-21T14:41:52.797 回答