Asp.net 我是否应该创建ChannelFactory<;T>;在每个需要呼叫服务的网页中?

Asp.net 我是否应该创建ChannelFactory<;T>;在每个需要呼叫服务的网页中?,asp.net,wcf,Asp.net,Wcf,我有10个网页,都需要调用ICalculatorService和IShoppingCartService的方法,它们都是WCF服务 我有一个ICalculatorService和IShoppingCartService的接口参考 我正在所有网页的PageLoad方法中创建ChannelFactory和ChannelFactory的实例 但这真的让网页速度变慢了,我不知道这是不是最好的办法 有没有更好的方法来实现这一功能?我建议创建一个简单的IHTTP模块来管理所有频道工厂,这样它们在web应用程

我有10个网页,都需要调用ICalculatorService和IShoppingCartService的方法,它们都是WCF服务

我有一个ICalculatorService和IShoppingCartService的接口参考

我正在所有网页的PageLoad方法中创建
ChannelFactory
ChannelFactory
的实例

但这真的让网页速度变慢了,我不知道这是不是最好的办法


有没有更好的方法来实现这一功能?

我建议创建一个简单的IHTTP模块来管理所有频道工厂,这样它们在web应用程序期间都可以使用,并且可以在所有页面上共享。

我不能谈论@Kirk Woll关于4.0的改进,因为我们仍然在使用3.5(我已经为我们的团队推荐了一个升级路径,但还没有得到批准)

我会做两件事,如果它真的是渠道工厂(评论中的一个争论点),或者它是你唯一可以选择(出于你无法控制的原因)来调整性能(我知道Kirk可能会不同意我:):

  • 仅在初始页面加载期间在页面上创建频道工厂-将其置于会话中,并在回发时将其拉出。您还可以将其放入缓存,并在页面加载时简单地在缓存中进行检查(无论回发状态如何),因为它在第一次创建时将一直可用,直到缓存过期

  • 在应用程序启动时缓存通道工厂(您可以在Global.asax代码中这样做)


  • 如果我要使用这两个选项中的任何一个,我会选择选项2。

    正如最初的评论所指出的,您应该验证ChannelFactory创建确实是性能问题的根源。这绝对是3.5版的问题

    这就是我使用的,最初在3.5天内实现。这将缓存ChannelFactory,在ChannelFactory级别处理任何故障,以及管理为每个发送请求创建一个通道并正确关闭通道。下面是这个类的代码

    像这样使用它:

    var sum = cachedCalculatorService.Send(proxy => proxy.Add(2, 2));
    
    为需要与之通信的每个服务创建一个ServerProxyFactory。将此缓存在您最喜欢的位置以持久化单例(@Tim有一些好的建议)

    e、 g

    ServerChannelFactory是线程安全的,因此您可以在任意多个线程中重用它

    希望这有帮助

    代码如下:

    namespace WcfHelper
    {
        using System;
        using System.Diagnostics.CodeAnalysis;
        using System.ServiceModel;
        using Microsoft.Commerce.Marketplace.Common.Util;
    
        /// <summary>
        /// A WCF Proxy Factory suitable for server to server web service calls. A new channel will be created for all service communication.
        /// 
        /// All sends handle disposing of the Proxy channel properly. If the Proxy is requested directly, the caller is responsible for properly 
        /// closing/disposing it.
        /// </summary>
        public class ServerProxyFactory<TContract> : IDisposable where TContract : class
        {
            private readonly object syncObject = new object();
    
            public ServerProxyFactory(string endpointConfigurationName)
            {
                endpointConfigurationName.EnsureArgNotNullOrEmpty("endPointConfigurationName");
                this.endPointConfigurationName = endpointConfigurationName;
            }
    
            private readonly string endPointConfigurationName;
    
            private ChannelFactory<TContract> channelFactory;
    
            protected ChannelFactory<TContract> ChannelFactory
            {
                get { return this.channelFactory; }
                set
                {
                    ChannelFactory<TContract> oldFactory;
    
                    lock (this.syncObject)
                    {
                        oldFactory = this.channelFactory;
    
                        if (oldFactory != null)
                        {
                            oldFactory.Faulted -= this.ChannelFactory_Faulted;
                        }
    
                        var newChannelFactory = value;
                        if (newChannelFactory != null)
                        {
                            newChannelFactory.Faulted += this.ChannelFactory_Faulted;
                        }
    
                        this.channelFactory = newChannelFactory;
                    }
    
                    if (oldFactory != null)
                    {
                        try
                        {
                            ((IDisposable)oldFactory).Dispose();
                        }
                        catch (CommunicationException)
                        {
                            oldFactory.Abort();
                        }
                        catch (TimeoutException)
                        {
                            oldFactory.Abort();
                        }
                        catch (Exception)
                        {
                            oldFactory.Abort();
                            throw;
                        }
                    }
                }
            }
    
    
            protected TContract Proxy
            {
                get
                {
                    if (this.disposed)
                    {
                        throw new InvalidOperationException(
                            "A new Proxy was requested after the ServerProxyFactory has been disposed.");
                    }
    
                    if (this.ChannelFactory == null)
                    {
                        this.ChannelFactory = new ChannelFactory<TContract>(this.endPointConfigurationName);
                    }
    
                    return this.ChannelFactory.CreateChannel();
                }
            }
    
            /// <summary>
            /// Perform a WCF call specified by serviceCall delegate 
            /// </summary>
            /// <typeparam name="TResult"></typeparam>
            /// <param name="serviceCallDelegate"></param>
            /// <returns>return value returned by the WCF call</returns>
            [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily")]
            public virtual TResult Send<TResult>(Func<TContract, TResult> serviceCallDelegate)
            {
                TResult result;
                TContract proxy = this.Proxy;
                try
                {
                    result = serviceCallDelegate(proxy);
                }
                finally
                {
                    try
                    {
                        ((IDisposable)proxy).Dispose();
                    }
                    catch (CommunicationException)
                    {
                        ((ICommunicationObject)proxy).Abort();
                    }
                    catch (TimeoutException)
                    {
                        ((ICommunicationObject)proxy).Abort();
                    }
                    catch (Exception)
                    {
                        ((ICommunicationObject)proxy).Abort();
                        throw;
                    }
                }
    
                return result;
            }
    
            /// <summary>
            /// Perform a WCF call specified by serviceCall delegate 
            /// </summary>
            /// <param name="serviceCallDelegate"></param>
            [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily")]
            public virtual void Send(Action<TContract> serviceCallDelegate)
            {
                TContract proxy = this.Proxy;
                try
                {
                    serviceCallDelegate(proxy);
                }
                finally
                {
                    if (proxy != null)
                    {
                        try
                        {
                            ((IDisposable)proxy).Dispose();
                        }
                        catch (CommunicationException)
                        {
                            ((ICommunicationObject)proxy).Abort();
                        }
                        catch (TimeoutException)
                        {
                            ((ICommunicationObject)proxy).Abort();
                        }
                        catch (Exception)
                        {
                            ((ICommunicationObject)proxy).Abort();
                            throw;
                        }
                    }
                }
            }
    
            private void ChannelFactory_Faulted(object sender, EventArgs e)
            {
                var factory = (ICommunicationObject)sender;
                if (factory == this.ChannelFactory)
                {
                    this.ChannelFactory = null;
                }
            }
    
            #region IDisposable Members
    
            // Track whether Dispose has been called.
            private bool disposed;
    
            // Implement IDisposable.
            public void Dispose()
            {
                this.Dispose(true);
                GC.SuppressFinalize(this);
            }
    
            protected virtual void Dispose(bool disposing)
            {
                if (disposing)
                {
                    this.ChannelFactory = null;
                }
                this.disposed = true;
            }
    
            #endregion
        }
    }
    
    名称空间WcfHelper
    {
    使用制度;
    使用System.Diagnostics.CodeAnalysis;
    使用System.ServiceModel;
    使用Microsoft.Commerce.Marketplace.Common.Util;
    /// 
    ///适用于服务器到服务器web服务调用的WCF代理工厂。将为所有服务通信创建一个新通道。
    /// 
    ///所有发送正确处理代理通道。如果直接请求代理,则调用方负责正确处理
    ///关闭/处理它。
    /// 
    公共类ServerProxyFactory:IDisposable,其中TContract:class
    {
    私有只读对象syncObject=新对象();
    公共服务器ProxyFactory(字符串endpointConfigurationName)
    {
    endpointConfigurationName.EnsureArgNotNullOrEmpty(“endpointConfigurationName”);
    this.endPointConfigurationName=endPointConfigurationName;
    }
    私有只读字符串endPointConfigurationName;
    私营渠道工厂;
    保护通道工厂通道工厂
    {
    获取{返回this.channelFactory;}
    设置
    {
    渠道工厂老厂;
    锁定(此.syncObject)
    {
    oldFactory=this.channelFactory;
    如果(旧工厂!=null)
    {
    oldFactory.Faulted-=this.ChannelFactory\u Faulted;
    }
    var newChannelFactory=值;
    if(newChannelFactory!=null)
    {
    newChannelFactory.Faulted+=this.ChannelFactory\u Faulted;
    }
    this.channelFactory=newChannelFactory;
    }
    如果(旧工厂!=null)
    {
    尝试
    {
    ((IDisposable)oldFactory).Dispose();
    }
    捕获(通信异常)
    {
    oldFactory.Abort();
    }
    捕获(超时异常)
    {
    oldFactory.Abort();
    }
    捕获(例外)
    {
    oldFactory.Abort();
    投掷;
    }
    }
    }
    }
    受保护的TContract代理
    {
    得到
    {
    如果(本文件已处理)
    {
    抛出新的InvalidOperationException(
    “在处置ServerProxyFactory后请求了新代理。”);
    }
    if(this.ChannelFactory==null)
    {
    this.ChannelFactory=新的ChannelFactory(this.endPointConfigurationName);
    }
    返回此.ChannelFactory.CreateChannel();
    }
    }
    /// 
    ///执行serviceCall委托指定的WCF调用
    /// 
    /// 
    /// 
    ///WCF调用返回的返回值
    [SuppressMessage(“Microsoft.Performance”、“CA1800:DonotCast不必要”)]
    公共虚拟树结果发送(Func serviceCallDelegate)
    {
    结果结果;
    t合同代理=此.proxy;
    尝试
    
    namespace WcfHelper
    {
        using System;
        using System.Diagnostics.CodeAnalysis;
        using System.ServiceModel;
        using Microsoft.Commerce.Marketplace.Common.Util;
    
        /// <summary>
        /// A WCF Proxy Factory suitable for server to server web service calls. A new channel will be created for all service communication.
        /// 
        /// All sends handle disposing of the Proxy channel properly. If the Proxy is requested directly, the caller is responsible for properly 
        /// closing/disposing it.
        /// </summary>
        public class ServerProxyFactory<TContract> : IDisposable where TContract : class
        {
            private readonly object syncObject = new object();
    
            public ServerProxyFactory(string endpointConfigurationName)
            {
                endpointConfigurationName.EnsureArgNotNullOrEmpty("endPointConfigurationName");
                this.endPointConfigurationName = endpointConfigurationName;
            }
    
            private readonly string endPointConfigurationName;
    
            private ChannelFactory<TContract> channelFactory;
    
            protected ChannelFactory<TContract> ChannelFactory
            {
                get { return this.channelFactory; }
                set
                {
                    ChannelFactory<TContract> oldFactory;
    
                    lock (this.syncObject)
                    {
                        oldFactory = this.channelFactory;
    
                        if (oldFactory != null)
                        {
                            oldFactory.Faulted -= this.ChannelFactory_Faulted;
                        }
    
                        var newChannelFactory = value;
                        if (newChannelFactory != null)
                        {
                            newChannelFactory.Faulted += this.ChannelFactory_Faulted;
                        }
    
                        this.channelFactory = newChannelFactory;
                    }
    
                    if (oldFactory != null)
                    {
                        try
                        {
                            ((IDisposable)oldFactory).Dispose();
                        }
                        catch (CommunicationException)
                        {
                            oldFactory.Abort();
                        }
                        catch (TimeoutException)
                        {
                            oldFactory.Abort();
                        }
                        catch (Exception)
                        {
                            oldFactory.Abort();
                            throw;
                        }
                    }
                }
            }
    
    
            protected TContract Proxy
            {
                get
                {
                    if (this.disposed)
                    {
                        throw new InvalidOperationException(
                            "A new Proxy was requested after the ServerProxyFactory has been disposed.");
                    }
    
                    if (this.ChannelFactory == null)
                    {
                        this.ChannelFactory = new ChannelFactory<TContract>(this.endPointConfigurationName);
                    }
    
                    return this.ChannelFactory.CreateChannel();
                }
            }
    
            /// <summary>
            /// Perform a WCF call specified by serviceCall delegate 
            /// </summary>
            /// <typeparam name="TResult"></typeparam>
            /// <param name="serviceCallDelegate"></param>
            /// <returns>return value returned by the WCF call</returns>
            [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily")]
            public virtual TResult Send<TResult>(Func<TContract, TResult> serviceCallDelegate)
            {
                TResult result;
                TContract proxy = this.Proxy;
                try
                {
                    result = serviceCallDelegate(proxy);
                }
                finally
                {
                    try
                    {
                        ((IDisposable)proxy).Dispose();
                    }
                    catch (CommunicationException)
                    {
                        ((ICommunicationObject)proxy).Abort();
                    }
                    catch (TimeoutException)
                    {
                        ((ICommunicationObject)proxy).Abort();
                    }
                    catch (Exception)
                    {
                        ((ICommunicationObject)proxy).Abort();
                        throw;
                    }
                }
    
                return result;
            }
    
            /// <summary>
            /// Perform a WCF call specified by serviceCall delegate 
            /// </summary>
            /// <param name="serviceCallDelegate"></param>
            [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily")]
            public virtual void Send(Action<TContract> serviceCallDelegate)
            {
                TContract proxy = this.Proxy;
                try
                {
                    serviceCallDelegate(proxy);
                }
                finally
                {
                    if (proxy != null)
                    {
                        try
                        {
                            ((IDisposable)proxy).Dispose();
                        }
                        catch (CommunicationException)
                        {
                            ((ICommunicationObject)proxy).Abort();
                        }
                        catch (TimeoutException)
                        {
                            ((ICommunicationObject)proxy).Abort();
                        }
                        catch (Exception)
                        {
                            ((ICommunicationObject)proxy).Abort();
                            throw;
                        }
                    }
                }
            }
    
            private void ChannelFactory_Faulted(object sender, EventArgs e)
            {
                var factory = (ICommunicationObject)sender;
                if (factory == this.ChannelFactory)
                {
                    this.ChannelFactory = null;
                }
            }
    
            #region IDisposable Members
    
            // Track whether Dispose has been called.
            private bool disposed;
    
            // Implement IDisposable.
            public void Dispose()
            {
                this.Dispose(true);
                GC.SuppressFinalize(this);
            }
    
            protected virtual void Dispose(bool disposing)
            {
                if (disposing)
                {
                    this.ChannelFactory = null;
                }
                this.disposed = true;
            }
    
            #endregion
        }
    }