我有一个MVC应用程序,并尝试启动一个线程来运行作业调度。我在Global.asax中使用Application_Start来启动线程,使用Application_End来再次停止线程。
但有时当网站有访问者并且我部署了新版本时,Application_Start会被多次触发。
在Application_Start的Global.asax中,我这样做:
BatchClient.Start();
这里有一些我的BatchClient代码:
public static class BatchClient
{
public static readonly List<BatchTask> BatchTaskList = new List<BatchTask>();
public static bool AllowToRun = true;
private static Thread handleThread = null;
public static void Start()
{
if (handleThread == null)
{
AddToInstanceLog("Start - in progress");
Setup();
handleThread = new Thread(Handler);
handleThread.Name = "NextBatchClient.Handler";
handleThread.Start();
ThreadUtil.AddThread(handleThread);
AddToInstanceLog("Start - done");
}
else
{
AddToInstanceLog("Allready running");
}
}
}
除非Application_Start多次调用,否则handleThread每次都为null,因此它只是启动一个新线程 - 然后我的作业多次运行。
怎么办? : - )
答案 0 :(得分:2)
重新设计您的应用程序。您不应该使用app-pool进行批量活动。 windows有这种操作的服务和调度程序。
以下是应用程序池中不应该有后台作业的首要原因。应用程序池回收,并且不是为托管批处理创建的,Recyle意味着它会停止进程并重新启动。进程中运行的所有线程都将被终止。它有一些保护可以防止您的请求线程突然死亡,但对于您所做的任何类型都没有。
建议您如何解决它。
答案 1 :(得分:1)
您是否看过专为此设计的解决方案?为什么重新发明轮子?
然后您可以执行以下操作:
BackgroundJob.Enqueue(BatchClient.Start(););
或者您可以添加重复作业:
RecurringJob.AddOrUpdate(() => BatchClient.Start(), Cron.Daily);