我正在开发一个部署在IIS-8中的asp.net mvc 5 Web应用程序,我在我的应用程序中有一个方法来执行一个长时间运行的任务,主要是扫描我们的网络以查找服务器和VM并使用扫描结果更新我们的数据库。方法执行可能需要持续30-40分钟才能完成生产环境。我正在使用一个名为Hangfire的计划工具,它将每天调用此方法2次。
这是startup.cs文件中的作业定义,它将调用8:01 am
&的方法。 8:01 pm
: -
public void Configuration(IAppBuilder app)
{
var options = new SqlServerStorageOptions
{
PrepareSchemaIfNecessary = false
};
GlobalConfiguration.Configuration.UseSqlServerStorage("scanservice",options);
RecurringJob.AddOrUpdate(() => ss.Scan(), "01 8,20 ***");
}
以下是日程安排工具每天调用两次的方法: -
public void Scan()
{
Service ss = new Service();
ss.NetworkScan().Wait();
}
最后,进行实际扫描的方法是(我只提供该方法的高级描述): -
public async Task<ScanResult> NetworkScan()
{
// retrieve the server info from the DB
// loop over all servers & then execute some power shell commands to scan the network & retrieve the info for each server one by one...
// after the shell command completed for each server, i will update the related server info inside the DB
目前我对我们的测试环境进行了一些测试,并且每件事都运行良好,扫描大约需要25秒才能扫描2台测试服务器。但现在我们计划将应用程序转移到生产环境中,我们有大约120个++要扫描的服务器。所以我估计方法执行需要大约30-40分钟才能完成生产环境。所以我的问题是如何确保此执行永不过期,ScanNetwork()方法将完成直到最后?
答案 0 :(得分:1)
您可以为每台服务器启动新任务,而不是担心您的任务超时。这样,每个任务都将非常短暂,扫描单个服务器引起的任何异常都不会影响所有其他任务。此外,如果您的应用程序在IIS中重新启动,则将恢复尚未完成的任何扫描。由于所有扫描都发生在一个顺序任务中,这是不可能的。您可能还会看到完成整个网络扫描的总时间,因为大部分时间可能会花在等待远程服务器上。
public void Scan()
{
Service ss = new Service();
foreach (var server in ss.GetServers())
{
BackgroundJob.Enqueue<Service>(s => s.ServerScan(server));
}
}
现在,您的计划任务只会为每个服务器排队一个新任务。