
ASP.NET Web服务能够向您提供保持任务逻辑的现有ASP.NET应用程序的接口。该接口充当该服务和调用ASP.NET应用程序以采取操作的Windows服务之间的中间人。Windows服务随后将按照预定时间间隔调用ASP.NET应用程序。通过在现有ASP.NET应用程序中生成ASP.NET Web服务,可以在预定作业中重新使用已经为该ASP.NET应用程序创建的业务对象和逻辑。图2显示应用程序流程的详细信息——从客户端Windows服务应用程序到在该服务器上运行的Web服务启动,始终贯穿于每个预定任务的执行。

正如您可以在图3中看到的那样,该过程要求对前面描述的标准分层进行一些修改。Windows服务将按照指定的时间间隔唤醒ASP.NET Web服务。然后,ASP.NET Web服务将调用Web应用程序流程层中的方法,以实际确定应当运行哪些预定作业,并随后运行它们。在实现了基本解决方案以后,您可以使用客户端app.config文件来确定Windows服务调用Web服务的时间间隔。接下来,您可以添加业务流程层所需要的功能,以便遍历和运行作业。许多N层专家对于流程层的兴趣肯定超过了对其余层的兴趣,因此我将最后讨论数据库表、数据库存储过程、数据访问代码和业务逻辑。最后,从底部(数据库表级别)到中部(业务逻辑层)向应用程序的现有层中添加代码,以便支持流程层所使用的作业功能。
生成Web服务
要生成Web服务,请首先向与现有ASP.NET代码位于相同层中的ASP.NET应用程序中添加JobRun ASP.NET Web服务。确保您的ASP.NET项目具有对业务逻辑、流程和数据访问项目的引用。接下来,要在JobRun Web服务中创建RunJob Web服务方法,Web服务方法将需要调用流程层的相应函数以运行适当的作业。这意味着RunJob方法可以像下面一样简单:
[WebMethod]
public void RunJob()
{
Flow.JobFlow jf = new Flow.JobFlow();
jf.RunAllActiveJobs();
}
使用RunJob函数创建JobFlow类(它位于流程层中)的实例并调用它的RunAllActiveJobs函数。JobFlow函数的RunAllActiveJobs完成了协调作业运行的所有实际工作,而RunJob函数只是充当该序列的入口点。请注意,这段代码无法防止作业同时在一个以上的线程中运行——如果Windows服务过于频繁地安排任务(速度超过了任务的运行速度),或者如果其他某个应用程序调用了入口点,则可能发生这种情况。如果该方法不是线程安全的并且允许多个线程同时调用它,则可能给这些作业的结果带来问题。例如,如果作业X向Mary Smith发送了一封电子邮件,但是在作业Y查询数据库以处理其电子邮件时尚未更新数据库,则Mary可能收到两封电子邮件。为了同步对该函数的访问,我将使用System.Threading命名空间中的Mutex类:
private static Mutex mut = new Mutex(false, "JobSchedulerMutex");
Mutex支持跨进程同步,因此这可以防止多个进程同时运行——即使涉及到两个不同的ASP.NET辅助进程。现在,让我们更改RunJob方法以使用Mutex,从而确保在启动作业之前没有其他作业运行。
代码段1 RunJob Web Service:
[WebMethod]
public bool RunJob()
{
bool ranJob = false;
mut.WaitOne();
try
{
Flow.JobFlow jf = new Flow.JobFlow();
jf.RunAllActiveJobs();
ranJob = true;
}
finally
{
mut.ReleaseMutex();
}
return ranJob;
}
正如您可以在代码段1中的RunJob函数中看到的那样,可以调用Mutex的WaitOne函数以使该线程等待,直到它在执行之前成为唯一的线程。然后,调用ReleaseMutex函数以指示您已经执行完只需要在一个线程中运行的代码。当然,在这里阻塞可能不是正确的解决方案。您可以选择在另一个线程已经执行作业时(在此情况下,您可以为WaitOne方法指定短暂的超时)立即返回,并且在无法获得互斥锁时立即从RunJob中返回。将该函数的所有主要操作都放到一个try-finally块中,以便即使RunAllActiveJobs函数中的意外异常导致RunJob函数退出,也会调用ReleaseMutex。
您可能希望使用某种形式的身份验证和授权(可能使用Windows安全)来保证 Web服务的安全,以确保必须经过正确的授权才能运行该服务,但是我不打算在本文对此进行详细讨论。
既然您已经生成了Web服务以便可以从另一个应用程序中调用它,那么现在就让我们生成能够使用它的Windows服务。
做人要厚道,请注明转自酷网动力(www.ASPCOOL.COM)。

