MVC应用程序中的作业调度

时间:2015-07-09 09:45:53

标签: c# asp.net-mvc multithreading

我有一个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,因此它只是启动一个新线程 - 然后我的作业多次运行。

怎么办? : - )

2 个答案:

答案 0 :(得分:2)

重新设计您的应用程序。您不应该使用app-pool进行批量活动。 windows有这种操作的服务和调度程序。

以下是应用程序池中不应该有后台作业的首要原因。应用程序池回收,并且不是为托管批处理创建的,Recyle意味着它会停止进程并重新启动。进程中运行的所有线程都将被终止。它有一些保护可以防止您的请求线程突然死亡,但对于您所做的任何类型都没有。

建议您如何解决它。

  • 使用服务应用程序。
  • 使用预定任务
  • 使用您可以安排的Azure webjob

答案 1 :(得分:1)

您是否看过专为此设计的解决方案?为什么重新发明轮子?

查看Hangfire.io

然后您可以执行以下操作:

BackgroundJob.Enqueue(BatchClient.Start(););

或者您可以添加重复作业:

RecurringJob.AddOrUpdate(() => BatchClient.Start(), Cron.Daily);