16

IIS / WCF実装の多くの問題を最初からテストするために、HelloWorldサービスを構築し、クライアントがここで(非常にうまく)ウォークスルーしました。net.tcpのエンドポイントを追加しましたが、サービスは、 HWと呼ばれるIIS 7.5独自の(Windows 7の)両方のバインディングに対してエンドツーエンドで適切に機能しています。ApplicationPool

私が機能させようとしているのは、発表されたAutoStartおよびPreload(または「プリウォームキャッシング」)機能です。私はここここに示されている指示に従いました(互いに非常に似ていますが、セカンドオピニオンを持っていることは常に良いことです)。つまり私は

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またはより広いウェブのいずれかで、この機能についてのイライラするほどの議論はほとんどなく、ここでのいくつかの同様の質問はほとんど注目されませんでした。おそらく不必要ですが、この道を1、2回気にかけていた専門家はいますか?(ソリューションをホストするのに適した場所を提案できる場合は、ソリューション全体を提供できれば幸いです。)


編集:メソッド内のそのパスをPreload相対App_Dataフォルダーにリセットしようとしました(別のSOの回答が示唆しています)、問題ではありませんでした。w3wp.exeまた、ローカルホストへの単純な参照でプロセスが起動することも学びました。このプロセスは、17 MBのメモリを消費して、単一の小さなOperationContractを提供しますが、価格はゼロのプリロード値を提供します。17MBのColdDeadCache。

4

4 に答える 4

4

これは、問題に対するわずかに異なるアプローチです。

  1. サービスの自動開始にはWindowsServerAppFabricを使用します
  2. WCFインフラストラクチャを使用してカスタムスタートアップコードを実行する

Re 1:Appfabric AutoStart機能はそのままで機能するはずです(MVCのServiceRouteを使用してサービスを登録していない場合は、Web.configのserviceActivationsセクションまたは物理*.svcファイルを使用して指定する必要があります。

Re 2:カスタムスタートアップコードを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
{

}

これは、私たちがかなり長い間、多くのサービスで使用してきた正確なアプローチです。(IISインフラストラクチャに依存するのではなく)カスタムスタートアップコードにWCFを使用することの追加の利点はServiceBehavior、任意のホスティング環境(セルフホストを含​​む)で機能し、より簡単にテストできることです。

于 2012-05-15T11:42:48.350 に答える
3

これはばかげているように聞こえますが、同じ問題に直面しました(構成を変更した後、w3wp.exeが自動的に起動しない)。これは、applicationHost.configファイルを編集しているときに管理者モードでテキストエディターを実行していなかったためです。私の側の愚かな間違い。

私の弁護では、Notepad ++を使用していました。これは、実際には保存されていないのに保存されていることを示しています。

于 2013-08-14T17:45:36.893 に答える
1

私も同じことをしました。できます...

プリロード方式では、ここで入手できる素敵なホワイトペーパーからいくつかのコードをコピーしています!

プリロードメソッドは次のようになります...

 public void Preload(string[] parameters) 
 {     
        bool isServceActivated = false; 
        int attempts = 0; 
        while (!isServceActivated && (attempts <10)) 
        {
            Thread.Sleep(1 * 1000);
            try
            {
                string virtualPath = "/Test1/Service1.svc";
                ServiceHostingEnvironment.EnsureServiceAvailable(virtualPath);
                isServceActivated = true;
            }
            catch (Exception exception)
            {
                attempts++;
                //continue on these exceptions, otherwise fail fast 
                if (exception is EndpointNotFoundException ||
                    exception is ServiceActivationException || 
                    exception is ArgumentException) 
                {
                    //log 
                }
                else
                {
                    throw;
                }
            }
        }
   }
于 2012-05-16T12:42:55.940 に答える
1

たぶんあなたは64ビットシステムを使用していますか?Windowsには、保存が32ビットフォルダにリダイレクトされるため、変更が反映されないという既知の「機能」があります。

(回答が見つけやすいので、コメントを回答に変換しました)

于 2014-12-16T09:51:04.477 に答える