1

インスタンス モードが Single で同時実行モードが Multiple の WCF サービスがあります。次のコードがあります。

    public static ICmsDataServiceWcf data
    {
        get
        {
            if (HttpContext.Current != null && HttpContext.Current.Session != null && HttpContext.Current.Session["DataService"] == null)
            {
                HttpContext.Current.Session.Add("DataService", GetDataService());
            }

            if (HttpContext.Current != null && HttpContext.Current.Session != null && HttpContext.Current.Session["DataService"] != null)
            {
                return (ICmsDataServiceWcf)HttpContext.Current.Session["DataService"];
            }
            return GetDataService();
        }
    }

    private static ICmsDataServiceWcf GetDataService()
    {
        string url = ConfigurationManager.AppSettings["service_url"];
        EndpointAddress endPoint = new EndpointAddress(url);

            var binding = new WSHttpBinding(SecurityMode.None);

            CachedWebServiceChannelFactory<ICmsDataServiceWcf> cf = new CachedWebServiceChannelFactory<ICmsDataServiceWcf>(binding, endPoint);

            var channel = cf.CreateChannel();

            return channel;
    }

アイデアは、すべてのクライアントが独自の WCF クライアントを取得し、リクエストをブロックするだけであり、クライアントを複数回作成/破棄するオーバーヘッドに苦しむ必要がないということです。

最近、「サービスがビジー状態です」という例外がいくつか発生しています。これらのクライアントのほとんどは、ほとんどアイドル状態です。アイドル状態のクライアントはサーバー上のリソースを引き続き消費しますか? そのインスタンスは何らかの形でサーバー側に永続化されていますか?

これが問題を引き起こす可能性がある理由を誰かが見ることができますか? (セッションが放棄されるまで多くのクライアントを座らせることによるメモリの浪費を除いて-クライアントのプールを使用し、非アクティブ/エラーのあるクライアントを定期的に選別することを検討しています。)

ありがとう、

ジョー

編集:私は自分のプロキシを実装したことを忘れていました-それが影響を与えるかどうかはわかりません:

public class CachedWebServiceProxy<T> : RealProxy
{
    private Type _typeOfProxy;
    public object _channel;
    public CachedWebServiceProxy(Type typeOfProxy, object channel)
        : base(typeOfProxy)
    {
        _typeOfProxy = typeOfProxy;
        _channel = channel;
    }
    public override System.Runtime.Remoting.Messaging.IMessage Invoke(System.Runtime.Remoting.Messaging.IMessage msg)
    {
        try
        {
            var methodCall = msg as IMethodCallMessage;
            var methodInfo = methodCall.MethodBase as MethodInfo;
            object result = null;
    // Caching code removed
                result = methodInfo.Invoke(_channel, methodCall.Args);
            return new ReturnMessage(result, null, 0, methodCall.LogicalCallContext, methodCall);
        }
        catch (Exception ex)
        {
            // Throw the actual error fro mthe webservice
            if (ex is TargetInvocationException && ex.InnerException != null)
            {
                throw ex.InnerException;
            }
            throw ex;
        }
    }
}
4

2 に答える 2

2

ChannelFactoryチャネルごとに を作成し、ファクトリを破棄してからチャネルを保持する代わりに、 を作成してChannelFactory(これはコストのかかる作業です)、使用するChannelたびに をインスタンス化することをお勧めします。

チャネルを取得して保持することは、ベスト プラクティスではありません。チャネルを作成し、使用し、閉じて、破棄する必要があります。これは、データベース接続を保持するようなものです。明示的に削除しない限り、破棄されることはありません。

private CachedWebServiceChannelFactory<ICmsDataServiceWcf> factory;

public ICmsDataServiceWcf GetDataService()
{
    if (factory == null) // or factory needs rebuilding
    {
        string url = ConfigurationManager.AppSettings["service_url"];
        EndpointAddress endPoint = new EndpointAddress(url);
        var binding = new WSHttpBinding(SecurityMode.None);

        factory = new CachedWebServiceChannelFactory<ICmsDataServiceWcf>
            (binding, endPoint);
    }

    return factory.CreateChannel();
}

クローズ & ディスポーズを強制するには、このメソッドをusing

using (var client = GetDataService())
{
    // do stuff
} // client will be disposed upon reaching the end of the using block
于 2013-08-22T21:54:21.057 に答える
0

このhttp://weblogs.asp.net/pglavich/archive/2007/05/07/wcf-client-channel-pool-improved-client-performance.aspxを見つけました。これはまさに私が必要としているものに似ています。

于 2013-08-22T21:42:20.233 に答える