我使用了一个简单的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服务创建另一个项目或以其他任何方式实现?
答案 0 :(得分:5)
要从Windows服务应用程序调用Web服务,首先要从该Web服务生成DLL,然后实例化其命名空间。假设您拥有该Web服务的代码和/或知道其命名空间,您可以执行以下命令来执行此操作:
在命令行上执行以下行:
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的代理类文件。
将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\
目录。
在命令行上运行这两个命令:
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。)
通过Windows资源管理器导航至C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727
。您应该看到在该文件夹中创建的DLL具有类的名称(MyWebService.dll
)。将此文件复制到Service项目的bin
文件夹中。您需要将bin
文件夹设置为包含在项目中,然后右键单击该文件夹以添加>现有项目。选择DLL。导入后,选择DLL并将其属性更改为:
构建行动:内容
复制到输出目录:如果更新则复制(或根据需要复制)
右键点击参考>添加参考。导航到Web服务的bin
文件夹中的DLL。
右键点击参考>添加服务参考。假设您的Web服务正在运行,请获取其完整的URL(即http://localhost:777/MyWebService.asmx
)并将其放在地址行上。在Namespace文本框中,给它一些比ServiceReference1
更有意义的东西,但它不应该与MyWebService
(ASMX文件的名称/命名空间)相同。也许是MWS
。
在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服务,因为;