MVC 5 Shared Long Running Task

时间:2015-10-30 22:48:29

标签: c# asp.net-mvc-5 task

I have a long running action/method that is called when a user clicks a button on a internal MVC5 application. The button is shared by all users, meaning a second person can come in and click it seconds after it has been clicked. The long running task is updating a shared task window to all clients via SignalR.

Is there a recommended way to check if the task is still busy and simply notifying the user it's still working? Is there another recommended approach? (can't use external windows service for the work)

Currently what I am doing seems like a bad idea or I could be wrong and it's feasible. See below for a sample of what I am doing.

public static Task WorkerTask { get; set; }
public JsonResult SendData()
{
    if (WorkerTask == null)
    {
        WorkerTask = Task.Factory.StartNew(async () =>
        {
            // Do the 2-15 minute long running job
        });

        WorkerTask = null;
    }
    else
    {
        TempData["Message"] = "Data is already being exported. Please see task window for the status.";
    }

    return Json(Url.Action("Export", "Home"), JsonRequestBehavior.AllowGet);
}

1 个答案:

答案 0 :(得分:1)

我不认为你所做的事情会起作用。我看到三个问题:

  1. 您正在控制器上存储WorkerTask(我认为)。为每个请求创建一个新控制器。因此,将始终创建新的WorkerTask
  2. 如果#1不是真的,您仍然需要将WorkerTask的实例化包装在一个锁中,因为多个客户端可以同时进行WorkerTask == null检查。
  3. 您的网络应用程序中不应该有长时间运行的任务。应用程序池可以随时重新启动,以查看WorkerTask
  4. 如果您想跳过"不要在您的网络应用中长时间运行工作的最佳做​​法建议,您可以使用.NET 4.5.2中引入的HostingEnvironment.QueueBackgroundWorkItem开始长期运行的任务。您可以在HttpApplication.Cache中存储变量,以指示长时间运行的进程是否已启动。

    此解决方案存在多个问题(它无法在Web场中运行,应用程序池可能会死亡等)。更强大的解决方案是使用Quartz.net或Hangfire等。