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 に答える