【问题标题】:Access the same Task from multiple methods (actions)从多个方法(动作)访问同一个任务
【发布时间】:2017-05-01 01:44:42
【问题描述】:

我正在尝试通过异步控制器执行导入过程,在该控制器中我声明了一个任务,以便所有方法都可以访问它,但是当任务过程完成时,它变得空,我无法从另一个控制器中看到信息方法。

[SessionState(SessionStateBehavior.Disabled)]
public class ImportController : AsyncController
{  
 private Task<ResultObject> _myTask;

 public ActionResult Import()
 {
     _myTask = Task.Run(() => {
         //failed or Success
         return new ResultObject();
     });

     _myTask.Wait();

     return Json(new { success : _myTask.Result });
 }

 public ActionResult CheckImportProcess()
 {
     //here _myTask is Null
     if(_myTask.Status == TaskStatus.Running){
         return Content("IS RUNNIN");
     }
     else{
         return Content(_myTask.Result);
     }
 }

}

我该怎么做?

更新 我尝试使用 Hangfire 来执行此操作,但这是不可能的。我的导入方法应该返回一个错误列表,而使用 Hangfire 则无法访问运行的返回。

【问题讨论】:

  • 为什么方法应该访问 task 而不是结果?并不是说他们可以。每个请求都会产生一个不同的控制器实例。如果你想创建一个长期运行的作业,那不是这样做的。
  • 查看 Scott Hanselman 的 How to run Background Tasks in ASP.NET。它解释了为什么您的要求不起作用,如何使用 QueueBackgroundWorkItem 正确启动后台任务以及如何实现计划作业,例如使用 Hangfire

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


【解决方案1】:

每次您发出请求时都会创建一个新的ImportController 实例,因此非静态_myTask 字段将在每个其他请求中初始化为空值。

您可以通过将_myTask 设为静态来解决此问题,或者通过注入某种单例范围的管理器类来跟踪控制器范围之外的任务。

private static Task<ResultObject> _myTask;

但是,在目前的状态下,这将是非常脆弱的。如果两个不同的用户启动此任务会发生什么?它应该运行两次吗?您是否应该因为第二次开始而忘记第一次运行?您处理此问题的方式似乎很容易导致问题,我同意 Panagiotis 的观点,您可能应该使用不同的框架来触发和跟踪任务的状态。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多