如何自动启动C# WebService?

8

我编写了一个C# WebService。问题是,发布到IIS后,除非调用其任何方法,否则它不会自动启动。这非常令人沮丧,因为这个WebService必须在启动后立即执行一些后台工作(其构造函数执行)。如果重启IIS,WebService将一直处于空闲状态,直到调用其方法之一。有没有办法克服这个问题,并强制WebService在发布或IIS重新启动后立即执行其构造函数?


2
为什么这个问题由汉考克提出,但所有答案都由TomTom回复?初看很令人困惑。 - PetPaulsen
我对这个话题引发的回复数量和巨大兴趣感到惊讶。 :) - hancock
9个回答

10

如果它必须在启动后持续执行一些后台工作,为什么不使用Windows服务来实现?我认为你可以编写一个WCF服务,并将其托管在Windows服务中。这样,客户端仍然可以调用您的服务,服务可以执行其后台工作,并且不会依赖于IIS作为主机,因为主机Windows服务将在自己的进程中运行。


汤姆,为什么在现实世界中不能完成呢? :-) WCF 的美妙之处在于我可以在任何类型的主机上托管服务,并且在这种情况下可以利用 Windows 服务的优势。为什么不呢?请解释一下。 - Ashish Gupta
现实世界中,1:WCF服务可能是网站的一部分。2:可能在共享主机上公开 - 即无法安装。3:可能只需要一些启动,我不想在第一个请求上建立连接和编译。正如我所说 - IIS团队同意。 - TomTom
3
Ashish: 你对在Windows服务中托管WCF服务的选择是正确的,但这可能不应该是首选。 在IIS中托管可以让您获得与IIS应用程序池管理工具、故障转移、应用程序池重启等相关的优势——如果您进行自托管,所有这些都需要您自己实现。 在许多情况下,最佳架构是在IIS中托管WCF服务并处理请求,同时与执行后台处理的Windows服务协作。当然,这取决于应用程序。自托管服务也非常有用! - itowlson
1
我认为这不应该被打折。鉴于原始问题,Ashish的建议是有效的,几乎肯定应该使用Windows服务而不是IIS作为主机。他正确地指出,您甚至可以在没有安装IIS的计算机上从任何代码中托管WCF服务。 IIS通常是更明智的服务主机选择,但这并不使此选项无效-决策取决于OP。 - Dan Puzey
1
@itowlson +1:对此表示赞同 :- "最佳架构是将 WCF 服务托管在 IIS 中处理请求,并与执行后台处理的 Windows 服务进行协作" - Ashish Gupta
显示剩余4条评论

4
如果你需要它一直运行,那么你的设计有缺陷。相反,应该创建一个 Windows 服务。

4
相反,TomTom,这正是Windows服务设计的“真实世界”场景。正如Axyradax所说,Web服务并不是用来持续执行后台工作的,它存在于为请求提供服务。而Windows服务则存在于持续执行后台工作和/或为请求提供服务。仅仅因为“Web服务”中有“服务”这个词,并不意味着它能够或者应该执行Windows服务的工作。 - itowlson
2
“仅仅因为”Web服务“中有”服务“一词,并不意味着它能或应该执行Windows服务的工作。” - Ashish Gupta
3
我不确定IIS团队是否同意你的观点。你把预热(大家都认为是有用的)和持续后台处理混淆了。如果IIS团队希望人们将w3wp.exe用作通用服务主机,他们肯定会制作一个后台处理实用程序而不仅仅是一个预热实用程序。 - itowlson
3
@TomTom - 不,那不是一个有效的情况。在这种情况下,您应该创建一个Windows服务来持续检索数据,然后创建一个Web服务来与Windows服务通信以检索其缓存的数据。每种类型的服务都按照其设计的方式进行操作。不要因为自己缺乏知识和错误的架构而混淆所有其他人都是错误的。 - Greg Beech
2
@TomTom - 但是你确实回答了,你没有解释你所假设的限制,并且你也没有建议使用Windows服务。我之所以没有回答是因为Ashish已经发表了一个好的回答,所以我只是投了一票;重复信息没有意义。 - Greg Beech
显示剩余5条评论

3
我认为Web服务并不适合持续进行一些后台工作 - 它只是用来响应其方法的请求。

这忽略了保持服务运行仍然是有益的事实。我有一个系统的前端,其中登录需要15-20秒。我不想在用户请求某些内容时立即登录 - 我希望系统预热并保持温暖。 - TomTom
你能详细解释一下吗?我只是在权衡选择……为什么 Web 服务不能执行后台工作呢? - hancock
1
Web服务旨在成为服务器上运行的某些东西(例如数据库)的API接口。由于它只是一个接口,因此它本身并不执行实际工作。例如,如果我有一个家庭机器人,它的Web服务将只读取其状态并将命令添加到其数据库中(是的,我会制作一个带有数据库的机器人),而机器人的控制系统将解释这些命令并执行实际工作。 - Axarydax

1

Actually, you can run a Thread or a job automatically in "Global.asax.cs". E.g.

 public System.Threading.Thread schedulerThread = null;
 protected void Application_Start(Object sender, EventArgs e)
  {
    schedulerThread = new System.Threading.Thread(YourLoopBackgroudMethodHere);
    schedulerThread.Start();
  }
And Don't forget to close the thread when your site application end.

protected void Application_End(Object sender, EventArgs e)
  {
    if (null != schedulerThread)
    {
      schedulerThread.Abort();
    }
  }

线程或任务将在您的网站程序运行时自动运行! - jujusharp
该 Web 服务目前没有 Global.asax 文件。如果我添加了它,我可以从那里自动启动它吗? - hancock
抱歉,我好几天没登录这个网站了。是的,你可以在项目中创建一个Global.asax文件,并将代码添加到Start函数中。希望你已经解决了这个问题! - jujusharp

1

您需要创建Windows服务。这里是创建用于定时任务的Windows服务的步骤。


1
除了(正确的)评注,即对于需要在后台运行的内容应该使用 Windows 服务:你能在 global.asax 中使用 Application_Start 事件吗?

3
据我所知,只有当网络服务收到第一个请求时,该事件才会发生。 - Jørn Schou-Rode
是的,它不会热启动应用程序。 - TomTom
该Web服务目前没有Global.asax文件。如果我添加了它,我可以从那里自动启动它吗? - hancock

1

我同意其他人的观点,你应该使用Windows服务。如果你正在使用WCF,你可以很容易地将你的Web服务托管在Windows服务中,兼顾两者的优势。请参考这篇MSDN文章进行教程。


看看共享主机在现实世界中的表现。可能不可行,可能会导致很多行政开销。有很多好的理由不要自己托管。 - TomTom

1

-1

我不同意。确保网络服务随计算机启动有很好的理由——允许它开始填充缓存或避免第一次执行缓慢。

IIS团队也支持这一点。这就是为什么他们开发了相应的功能:

http://www.iis.net/expand/ApplicationWarmUp

这个模块可以确保当IIS启动时,网站已经“热”了(也就是已经启动了)。


6
针对缓存密集型应用程序(以及Web服务),应用程序预热肯定是一个好主意,但问题是关于“持续的后台工作”。我认为,依靠应用程序预热来运行这样的后台工作是一种不正规的方式。 - Jonas Høgh
这取决于背景工作在做什么。它可以是“每30秒清理临时文件夹”,也可以是“每15秒挑选新的市场数据以暴露” - 在Web应用程序中,这些都是有效的持续后台工作。 - TomTom
3
你给出的所有例子都应该在Windows服务中完成,而不是Web服务。你提到无法安装Windows服务作为一个原因,然而你是唯一提到这个限制的人,这意味着这是纯推测,因此没有有效性。在一个Web服务中,持续工作是不适合的,它只应该响应请求 - Greg Beech
3
@TomTom说,你提供的工具并不会执行“后台工作”。它只是打开了一些页面以允许服务器预缓存数据并连接提供程序等,但这些仅需操作一次。它不能用于像原始问题所要求的“连续”任务的运行。 - Dan Puzey
3
关于应用程序回收的问题:在许多情况下,IIS会自动回收您的应用程序域。这不必是手动操作,任何愚蠢到关闭此功能的用户都应该承担后果。@TomTom,请注意。 - Dan Puzey
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接