我很难用这个。
所以在我的asp.net应用程序中有这样一种方法:
public CopyResponse thirdStage(CopyRequest request)
{
CopyCCResponse response = new CopyCCResponse();
Task.Run(() =>
{
performCopying(request);
});
return response;
}
private void performCopying(CopyCCRequest request)
{
using (Repository = new myDbContext())
{
// do some initial action
try
{
// in general it looks like below
foreach(var children in father)
{
var newChildren = chldren.Copy();
Repository.Childrens.Add(newChildren);
foreach (var grandchldren in children.grandchildrens)
{
var newGrandchildren = grandchldren.Copy();
newGrandchildren.Parent = newChildren;
Repository.Grandchildrens.Add(newGrandchildren);
}
Repository.SaveChanges();
}
}
catch (Exception ex)
{
// log that action failed
throw ex;
}
}
}
此方法和所有其他方法(有一些类似的方法)在本地计算机上的设计工作没有任何问题。
不幸的是,在另一个环境中,这些方法失败了:
您对我如何处理此问题有任何建议吗?
答案 0 :(得分:1)
您无法从IIS内部执行可靠的“即发即弃”任务,如果未提供该站点,则应用程序池将在一段时间后关闭其AppDomain
。
使用的两个选项是:
HostingEnvironment.QueueBackgroundWorkItem
告诉IIS您正在做背景工作。这将使服务器知道工作,并且在它终止进程之前,它将延迟关闭(最多默认最多90秒)。
public CopyResponse thirdStage(CopyRequest request)
{
CopyCCResponse response = new CopyCCResponse();
HostingEnvironment.QueueBackgroundWorkItem(() =>
{
performCopying(request);
});
return response;
}
另一个选择是使用专为在Hangfire.io等IIS中进行后台工作而设计的第三方库,这将在IIS内部运行一项服务,并尝试将实例保持活动直到工作已经完成了。您还可以将Hangfire配置为单独运行,因此您无需依赖IIS实例的生命周期。
public CopyResponse thirdStage(CopyRequest request)
{
CopyCCResponse response = new CopyCCResponse();
BackgroundJob.Enqueue(() =>
{
performCopying(request);
});
return response;
}
注意,使用具有单独进程的hangfire可能需要对performCopying(CopyCCRequest request)
进行一些重新设计以支持从单独的进程运行,从IIS实例内部使用它不需要任何更改。