wcf - 自动启动/预热功能在 IIS 7.5/WCF 服务中不起作用

标签 wcf configuration iis-7.5 application-pool autostart

为了从头开始测试 IIS/WCF 实现的许多令人头疼的问题,我构建了 HelloWorld 服务和客户端(非常好)here .我为 net.tcp 添加了端点,并且服务在 IIS 7.5 下的两个绑定(bind)中端到端正常工作(在 Windows 7 上)在它自己的 ApplicationPool称为硬件。

我正在尝试使用已宣布的 AutoStart 和 Preload(或“预热缓存”)功能。我已按照 here 中的说明进行操作和 here (彼此非常相似,但有第二个意见总是好的)非常密切。这意味着我

1)设置应用池startMode ...

<applicationPools> 
     <!-- ... -->
     <add name="HW" managedRuntimeVersion="v4.0" startMode="AlwaysRunning" /> 
</applicationPools>

2) ...启用serviceAutoStart并设置指向我的serviceAutoStartProvider的指针
<site name="HW" id="2">
    <application path="/" applicationPool="HW" serviceAutoStartEnabled="true" serviceAutoStartProvider="PreWarmMyCache" />
    <!-- ... -->
</site>

3) ...并使用 GetType().AssemblyQualifiedName 命名所述提供者下面完整列出的类
<serviceAutoStartProviders> 
    <add name="PreWarmMyCache" type="MyWCFServices.Preloader, HelloWorldServer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> 
</serviceAutoStartProviders>
using System;

namespace MyWCFServices
{
    public class Preloader : System.Web.Hosting.IProcessHostPreloadClient
    {
        public void Preload(string[] parameters)
        {
            System.IO.StreamWriter sw = new System.IO.StreamWriter(@"C:\temp\PreloadTest.txt");
            sw.WriteLine("Preload executed {0:G}", DateTime.Now);
            sw.Close();
        }
    }
}

唉,所有这些手动配置,加上一对 iisreset打电话,我什么也得不到。没有 w3wp.exe进程在任务管理器中启动(尽管如果我启动 HelloWorldClient 我会得到它),没有文本文件,最重要的是,不满意。

无论是在 SO 上还是在更广泛的网络上,关于此功能的讨论都非常少,而且这里的几个类似问题也很少受到关注,所有这些都敲响了一两个警钟。也许是不必要的——有哪位专家曾在这条路上走过一两次,愿意插话吗? (如果您能推荐一个托管它的好地方,很高兴提供整个解决方案。)

编辑 : 我尝试在 Preload 中重置该路径方法到相对App_Data文件夹(另一个 SO 答案建议),没关系。另外,我学会了w3wp.exe进程在简单浏览到 localhost 时触发。该过程消耗了令人印象深刻的 17MB 内存来提供其单个微小的 OperationContract,同时提供零预加载值的价格。 17MB 的 ColdDeadCache。

最佳答案

对于您的问题,这是一种略有不同的方法:

  • 使用Windows Server AppFabric服务自动启动
  • 使用 WCF 基础结构执行自定义启动代码

  • 回复 1:Appfabric AutoStart feature应该开箱即用(如果您没有使用 MVC 的 ServiceRoute 来注册您的服务,则必须在 Web.config 的 serviceActivations 部分或使用物理 *.svc 文件中指定它们。

    Re 2:要将自定义启动代码注入(inject) WCF 管道,您可以使用如下属性:
    using System;
    using System.ServiceModel;
    using System.ServiceModel.Description;
    
    namespace WCF.Extensions
    {
        /// <summary>
        /// Allows to specify a static activation method to be called one the ServiceHost for this service has been opened.
        /// </summary>
        [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
        public class ServiceActivatorAttribute : Attribute, IServiceBehavior
        {
            /// <summary>
            /// Initializes a new instance of the ServiceActivatorAttribute class.
            /// </summary>
            public ServiceActivatorAttribute(Type activatorType, string methodToCall)
            {
                if (activatorType == null) throw new ArgumentNullException("activatorType");
                if (String.IsNullOrEmpty(methodToCall)) throw new ArgumentNullException("methodToCall");
    
                ActivatorType = activatorType;
                MethodToCall = methodToCall;
            }
    
            /// <summary>
            /// The class containing the activation method.
            /// </summary>
            public Type ActivatorType { get; private set; }
    
            /// <summary>
            /// The name of the activation method. Must be 'public static void' and with no parameters.
            /// </summary>
            public string MethodToCall { get; private set; }
    
    
            private System.Reflection.MethodInfo activationMethod;
    
            #region IServiceBehavior
            void IServiceBehavior.AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
            {
            }
    
            void IServiceBehavior.ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
            {
                serviceHostBase.Opened += (sender, e) =>
                    {
                        this.activationMethod.Invoke(null, null);
                    };
            }
    
            void IServiceBehavior.Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
            {
                // Validation: can get method
                var method = ActivatorType.GetMethod(name: MethodToCall,
                                 bindingAttr: System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public,
                                 callConvention: System.Reflection.CallingConventions.Standard,
                                 types: Type.EmptyTypes,
                                 binder: null,
                                 modifiers: null);
                if (method == null)
                    throw new ServiceActivationException("The specified activation method does not exist or does not have a valid signature (must be public static).");
    
                this.activationMethod = method;
            }
            #endregion
        }
    }
    

    ..可以这样使用:
    public static class ServiceActivation
    {
        public static void OnServiceActivated()
        {
            // Your startup code here
        }
    }
    
    [ServiceActivator(typeof(ServiceActivation), "OnServiceActivated")]
    public class YourService : IYourServiceContract
    {
    
    }
    

    这正是我们在大量服务中使用了相当长一段时间的确切方法。使用 WCF 的额外好处 ServiceBehavior对于自定义启动代码(而不是依赖于 IIS 基础结构)来说,它可以在任何托管环境(包括自托管)中工作,并且可以更容易地进行测试。

    关于wcf - 自动启动/预热功能在 IIS 7.5/WCF 服务中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10468167/

    相关文章:

    c# - WCF 服务不喜欢单引号

    wcf - 使用WCF传输文件

    asp.net-mvc - WebService 还是简单的 MVC Controller ?

    java - 将配置传递给每个 GUI 对象的最佳实践

    powershell - IIS7.5 PowerShell preloadEnabled

    asp.net - 是否可以在 AZURE 的同一个网站门户中部署 WCF 服务和网站?

    perl 配置和 block

    configuration - 如何加载 CMake 项目的用户特定配置

    IIS 7.5 上的 ASP.NET MVC - 错误 403.14 禁止

    http-status-code-404 - IIS 服务器 .m3u8 扩展未打开