在 MVC3 Webapp 中安排任务时,我需要您的建议。
我的任务是为 webapp 中的不同服务创建一些通用调度程序,以便以后在开发中使用。例如,我们有一些可用的任务,用户可以随时安排。
我不想重新发明轮子,并找到了可用于创建调度程序的 Quartz.Net 库。
我知道在 webapp 中托管调度不是一个好主意,因为 webserver 可以回收应用程序池等,所以我决定在 Windows 服务中使用它,然后使用 Quartz.NET 远程处理功能在我的 webapp 中触发任务。
但我发现了一些问题。如果我错了,请纠正我,但是当我尝试使用 Quartz.NET 远程处理时,它会在 Windows 服务进程中运行该作业,这意味着它需要了解我的 webapp 中的所有类型,因此 webapp 的所有程序集应该被它引用,我需要另一个数据库配置文件等。所以如果我写新的作业类,我不能轻易安排它,我需要停止服务并为它更新库,所以这不是很通用的方法。
我找不到 Quartz.NET 只能基于其接口运行作业的任何信息。
所以我想出了编写自己的调度程序的想法,它将托管在 Windows 服务中,并且将具有一些将在 webapp 中实现的 IJob 接口。我还将通过 IPC 通道使用 .Net 远程处理。所以 webapp 就像 .Net Remoting Server,当我想添加一些新作业然后安排它时,我只需要编写实现 IJob 接口的新作业。我将其注册为
IpcChannel channel = new IpcChannel("CurrentIPC");
ChannelServices.RegisterChannel(channel);
RemotingConfiguration.RegisterWellKnownServiceType(
typeof(SimpleJob), "SimpleJob", WellKnownObjectMode.SingleCall);
RemotingConfiguration.RegisterWellKnownServiceType(
typeof(ComplexObject), "ComplexObject", WellKnownObjectMode.SingleCall);
在这种情况下,我将注册两种工作类型。然后在调度作业时,我将传递类的名称,在代表客户端的 Windows 服务端(在 webapp 端执行对象),我只需将传递的类名称与 IJob 绑定,如下所示:
Dictionary<string, IJob> jobs = new Dictionary<string, IJob>();
void AddJob(string name)
{
IJob obj = (IJob)Activator.GetObject(typeof(IJob), string.Format("ipc://CurrentIPC/{0}", name));
jobs.Add(name, obj);
}
所以现在我不需要担心对我的应用程序和其他东西的引用,调度程序会在不知道任何事情的情况下完成它的工作,只需要 IJob 接口并在 webapp 端执行任务。
如果我错了或者它太复杂了,还有其他一些更简单的方法可以做到这一点,或者有一些我不知道的陷阱,你能帮我吗?谢谢你。
PS 还有一个想法是有一个单独的调度程序,它将通过执行 Web 应用程序中指定服务的链接直接运行 Web 应用程序方法,例如“http://localhost:3030/Request/12”,仅此而已,但是在我的网络应用程序中,您应该被授权执行此类请求,并且我们再次遇到需要解决的问题,并且在数千个计划任务的情况下,我们将对此类请求的网络服务器产生额外的负载。