简体   繁体   中英

MVC 5 Shared Long Running 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);
}

I don't think what you're doing will work at all. I see three issues:

  1. You are storing the WorkerTask on the controller (I think). A new controller is created for every request. Therefore, a new WorkerTask will always be created.
  2. If #1 weren't true, you would still need to wrap the instantiation of WorkerTask in a lock because multiple clients could reach the WorkerTask == null check at the same time.
  3. You shouldn't have long running tasks in your web application. The app pool could restart at any time killing your WorkerTask .

If you want to skip the best practices advice of "don't do long running work in your web app", you could use the HostingEnvironment.QueueBackgroundWorkItem introduced in .NET 4.5.2 to kick off the long running task. You could store a variable in the HttpApplication.Cache to indicate whether the long running process has been kicked off.

This solution has more than a few issues (it won't work in a web farm, the app pool could die, etc.). A more robust solution would be to use something like Quartz.net or Hangfire.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM