Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在WCF启动时运行函数_C#_.net_Wcf_Rest - Fatal编程技术网

C# 在WCF启动时运行函数

C# 在WCF启动时运行函数,c#,.net,wcf,rest,C#,.net,Wcf,Rest,我不确定这是否可能,但我希望在WCF服务启动后尽快运行一个函数来生成初始缓存数据。我现在不担心如何实现缓存,我的问题是在服务启动时让函数运行。服务将是RESTful的 该服务最终将托管在IIS中,并使用.Net Framework 4.5最简单的方法是在WCF项目根目录下创建一个App\u code文件夹,创建一个类(我称之为Initializer,但这并不重要。重要的部分是方法名称),如下所示: 可以找到有关AppInitialize的更多信息。KirkWoll建议的方法有效,但前提是您在II

我不确定这是否可能,但我希望在WCF服务启动后尽快运行一个函数来生成初始缓存数据。我现在不担心如何实现缓存,我的问题是在服务启动时让函数运行。服务将是RESTful的


该服务最终将托管在IIS中,并使用.Net Framework 4.5

最简单的方法是在WCF项目根目录下创建一个
App\u code
文件夹,创建一个类(我称之为
Initializer
,但这并不重要。重要的部分是方法名称),如下所示:


可以找到有关AppInitialize的更多信息。

KirkWoll建议的方法有效,但前提是您在IIS中,并且这是Appu代码下唯一的AppInitialize静态方法。如果要基于每个服务执行初始化,如果使用不同的AppInitialize方法,或者如果不在IIS下,则可以使用以下其他选项:

  • 如果在IIS下使用.NET Framework 4.5,则可以使用服务运行时将调用的服务配置方法。更多信息请访问
  • 如果您是自托管服务,则可以控制服务何时启动(调用
    ServiceHost.Open()
    ),以便在那里初始化它
  • 如果您使用的是IIS,而不是4.5,则可以在打开服务主机时使用服务主机工厂和要调用的自定义服务主机。此时,您可以进行初始化。有关服务主机工厂的详细信息,请访问
自定义工厂的示例如下所示:

public class MyFactory : ServiceHostFactory
{
    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
    {
        ServiceHost host = base.CreateServiceHost(serviceType, baseAddresses);
        host.Opening += new EventHandler(host_Opening);
        return host;
    }

    void host_Opening(object sender, EventArgs e)
    {
        // do initialization here
    }
}

}在我的例子中,我喜欢下面的内容。我有一个承载WCF Rest服务的Windows服务项目。我在我的Windows服务项目MyService.cs中编写了以下代码

protected override void OnStart(string[] args)
{
    try
      {
        ServiceHost myServiceHost = new ServiceHost(typeof(myservice));
        myServiceHost.Opening += OnServiceHostOpening;
        myServiceHost.Open();
      }
      catch (Exception ex)
      {
         //handle exception
      }
}

private void OnServiceHostOpening(object sender, EventArgs e)
{
   //do something
}

这可能正是我想要的。服务是否托管在IIS中有关系吗?是的,事实上它需要IIS。我发现这是一个糟糕的选项。包含“AppInitialize”的模块不随项目一起编译,而是作为“内容”提供,并在加载服务时动态编译。因此,许多库需要未提供正确实施IOC的指南(例如系统反射)。虽然我同意只需要一个初始化方法,但这个解决方案受到动态编译的限制。@Draire1,您可以从
AppInitialize
调用程序集中的任何类,所以我不明白您的意思。我知道AppInitialized是动态编译的。如果IIS没有外部库,您会遇到“无法加载模块”异常。我试图将多个程序集馈送到MEF容器构造中,但IIS无法找到“System.Reflection”。我肯定我可以花几个小时构建一个应用程序池,其中包含我需要的所有程序集,但这太多了“ServiceHostFactory”的答案可以确保您需要的所有程序集都被编译到代码中。值得一提的是,这些选项对我都不起作用——我不得不使用
AppInitialize
,因为我要接管处理
.svc
自动生成的文件。但除此之外,我还需要使用
AppInitialize
回答得很透彻。我在使用IIS/4.5“服务配置方法”时遇到了一个奇怪的副作用:在“配置”中,我不得不添加下面的一行,因为它不再读取我的web.config文件设置,而且一切都乱七八糟:
config.LoadFromConfiguration()
@user240374非常有用的信息!阅读主答案中链接的MSDN页面,IIS/4.5“服务配置方法”的要点似乎是允许您在代码中配置服务,而不是从web.config文件中配置服务。因此,我想如果您有这些配置方法之一,IIS将忽略我发现这是一个巨大的缺点:
定义后,app.config或web.config文件中指定的任何服务配置设置都将被忽略。
我希望在启动时执行一些代码,但不禁用基于文件的配置。如果有人想要此链接,请声明“WCF ServiceHost类型具有两个称为打开和关闭的事件。它们是在服务启动和关闭时执行代码的唯一正确方法。”
protected override void OnStart(string[] args)
{
    try
      {
        ServiceHost myServiceHost = new ServiceHost(typeof(myservice));
        myServiceHost.Opening += OnServiceHostOpening;
        myServiceHost.Open();
      }
      catch (Exception ex)
      {
         //handle exception
      }
}

private void OnServiceHostOpening(object sender, EventArgs e)
{
   //do something
}