在Windows服务中调用Web服务

时间:2016-12-31 17:38:36

标签: c# asp.net web-services windows-services

我使用了一个简单的Windows服务来使方法在特定时间内工作,并且工作正常。之后我已经尝试过了:

protected override void OnStart(string[] args)
{
    this.WriteToFile("Simple Service started {0}");
    this.ScheduleService();
}

protected override void OnStop()
{
    this.WriteToFile("Simple Service stopped {0}");
    this.Schedular.Dispose();
}

private Timer Schedular;

public void ScheduleService()
{
    try
    {
        Schedular = new Timer(new TimerCallback(SchedularCallback));
        string mode = ConfigurationManager.AppSettings["Mode"].ToUpper();
        this.WriteToFile("Simple Service Mode: " + mode + " {0}");

        //Rest of the code here
    }
    catch(Exception ex)
    {
        WriteToFile("Simple Service Error on: {0} " + ex.Message + ex.StackTrace);

        //Stop the Windows Service.
        using (System.ServiceProcess.ServiceController serviceController = new System.ServiceProcess.ServiceController("SimpleService"))
        {
            serviceController.Stop();
        }
    }
}

这是在一个简单的Windows应用程序中完成的。所以我要做的是在Windows服务中调用Web服务(在特定时间运行的特定方法)。我正在构建的应用程序是基于Web的,我有点困惑如何将Windows服务集成到其中?我是否需要任何替代方案或任何建议将不胜感激。

注意:我想知道的是,是否需要在Web应用程序中为Windows服务创建另一个项目或以其他任何方式实现?

2 个答案:

答案 0 :(得分:5)

要从Windows服务应用程序调用Web服务,首先要从该Web服务生成DLL,然后实例化其命名空间。假设您拥有该Web服务的代码和/或知道其命名空间,您可以执行以下命令来执行此操作:

  1. 在命令行上执行以下行:

    cd C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools
    wsdl /l:CS /protocol:SOAP %svc%?WSDL

    其中%svc%是您的网络服务的网址,即http://localhost:777/MyWebService.asmx

    如果代码是VB而不是C#,请将/l:CS更改为/l:VB。 这将输出一个可以转换为DLL的代理类文件。

  2. MyWebService.cs文件从C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools移至C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\目录。

  3. 在命令行上运行这两个命令:
    cd C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727
    csc /t:library %name%.cs /reference:System.Web.Services.dll /optimize

    其中%name%是类的名称(没有.cs,因为命令会附加这个)。在我们的例子中,我们使用MyWebService。 (对于VB类,将.cs更改为.vb。)

  4. 通过Windows资源管理器导航至C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727。您应该看到在该文件夹中创建的DLL具有类的名称(MyWebService.dll)。将此文件复制到Service项目的bin文件夹中。您需要将bin文件夹设置为包含在项目中,然后右键单击该文件夹以添加>现有项目。选择DLL。导入后,选择DLL并将其属性更改为:

    构建行动:内容
    复制到输出目录:如果更新则复制(或根据需要复制)

  5. 右键点击参考>添加参考。导航到Web服务的bin文件夹中的DLL。

  6. 右键点击参考>添加服务参考。假设您的Web服务正在运行,请获取其完整的URL(即http://localhost:777/MyWebService.asmx)并将其放在地址行上。在Namespace文本框中,给它一些比ServiceReference1更有意义的东西,但它不应该与MyWebService(ASMX文件的名称/命名空间)相同。也许是MWS

  7. 在Windows服务中实例化您的网络服务:

    MWS.MyWebServiceSoapClient webService = new MWS.MyWebServiceSoapClient();
    webService.Open();
    string someDataYouWant = webService.SomeMethodToGetData();
    webService.Close();

    或者你可能会这样做:

    MyWebService webService = new MyWebService();
    string someDataYouWant = webService.SomeMethodToGetData();
    webService.Dispose();

答案 1 :(得分:1)

回答您对我的评论的询问;

另一种方法是使用支持Windows服务逻辑的IIS自动启动网站。 IIS自动启动优先于使用Windows服务,因为它包含所有IIS应用程序托管逻辑,包括自动重启和积极的资源管理。写得不好的Windows服务可以取消服务器,但是ASP.net IIS托管的应用程序需要花费很多东西来取下它的主机(这几乎是不可能的)。

您的自动启动网站无需向外界展示 - 它只需要一个内部计时器,以便在启动时保持活动状态。请注意,由于各种原因,IIS可能会启动和停止Web应用程序;但结果是,只要您的其他Web服务应用程序正在运行,它就会运行。内部计时器可以等待特定时间来执行调用第二个Web服务所需的逻辑。

要记住的关键是Windows服务被设计为由Windows托管并且不断运行的应用程序。 IIS应用程序旨在由Windows运行,但仅在调用时运行。 IIS自动启动网站概念允许您提供"持续运行"网站,但由强大的IIS应用程序托管组件托管,而不是直接作为操作系统进程运行。

通常人们不会这样做,因为要么他们不知道它,要么想避免需要IIS基础设施来运行" Windows服务"键入应用程序,但在您的情况下,您已经支付了使用IIS来托管第二个Web服务的成本,因此您也可以充分利用IIS(并避免第二个技术堆栈和Windows服务部署的部署难题)。 / p>

所以我建议在您的情况下使用IIS自动启动优先于Windows服务,因为;

  1. 您只需要在解决方案中使用技术堆栈,这就是您的OP所询问的内容
  2. IIS对其所有应用程序执行活动资源管理,如果它们不起作用则终止,重新启动。 Windows服务没有此功能。
  3. 您的基于IIS的服务代码是XCOPY可部署的,目标计算机上没有管理员访问凭据。
  4. 您的IIS服务可以热升级而无需操作系统级别的管理员权限 - IIS可以在升级时处理停止和重新启动,而无需您执行任何操作。