【问题标题】:Run async action method in background在后台运行异步操作方法
【发布时间】:2013-06-20 19:20:45
【问题描述】:

有什么方法可以在标准操作方法中调用异步操作方法而不等待异步方法执行(保持相同的请求对象)?

public class StandardController : Controller
{
    public ActionResult Save()
    {
        // call Background.Save, do not wait for it and go to the next line

        return View();
    }
}

public class BackgroundController : AsyncController
{
    public void SaveAsync()
    {
        // background work
    }
}

我尝试使用 Task 类来做后台工作,但是当我开始任务并且 action 方法返回了 View 时,Request 被杀死并且我的 DependencyResolver 实例被擦除,所以后台任务开始抛出异常。

第一个想法是执行 Standard.Save(不调用后台任务)并返回可以在 ajax 中调用 Background.Save 方法的 View。换句话说:向异步控制器调用另一个请求,以启动后台任务。

主要问题是如何调用异步方法来保存授权信息(在cookies中)和依赖解析器(在我的例子中:autofac)。

【问题讨论】:

  • 为什么一开始就直接调用控制器的方法?
  • 你可以直接调用它。如果必须等待,SaveAsync() 将在第一个 await 语句上将控制权返回给 Save()。如果要使用后台线程,请使用Task.Run()
  • 刚刚意识到SaveAsync 不是异步的。使其异步或使用Task.Run() 调用它
  • 好的,Task.Run() 会启动任务,但是当行“return View();”执行后,请求将被释放,后台任务将无法访问依赖解析器和请求上下文。
  • 我猜你的问题和这个相关问题stackoverflow.com/q/12319642/1236044中的问题类似

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


【解决方案1】:

您可以在同步代码中运行一些异步方法:

public class StandardController : Controller
{
    public ActionResult Save()
    {
        //code...
        YourMethod();
        //code...
        return View();
    }
    public async void YourMethod()
    {
      await Task.Run(()=>{
      //your async code...
      });
    }
}

YourMethod() 将在 Save() 完全执行之前和之后执行。

【讨论】:

    【解决方案2】:

    对我来说这很好用:

        public class PartnerController : Controller
        {
        public ActionResult Registration()
        {
            var model = new PartnerAdditional();
            model.ValidFrom = DateTime.Today;
            new Action<System.Web.HttpRequestBase>(MyAsync).BeginInvoke(this.HttpContext.Request, null, null);
            return View(model);
        }
    
        private void MyAsync(System.Web.HttpRequestBase req)
        {
            System.Threading.Thread.Sleep(5000);
            foreach (var item in req.Cookies)
            {
                System.Diagnostics.Debug.WriteLine(item);
            }
        }
    }
    

    页面被回发,大约 10 秒后异步出现在我的调试输出中。 不确定这将如何与 Cookie/身份验证信息一起使用,但您可以将值传递给该方法。

    希望对你有帮助。

    【讨论】:

    • 您没有从后台任务访问请求信息;只需写入调试控制台,这就是它起作用的原因。如果后台任务需要访问请求信息(甚至从中读取;假设它不写入响应),这将不起作用。
    • 当然我假设他不想修改Async方法中的请求。
      “如果后台任务需要访问请求信息(甚至读取请求信息;假设它不写入响应),这将不起作用。”他也可以传递httpContext.Request并从中读取,它不会dispose。
    • 他不需要修改它,但他需要访问它。引用这个问题,"The main problem is how to call the async method keeping the authorization information (in cookies) and dependency resolver (in my case: autofac)." 这根本没有解决这个问题。
    • 编辑了模板以显示我可以在后台线程中访问(例如)请求的 cookie。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-03
    • 2021-07-24
    • 1970-01-01
    • 1970-01-01
    • 2016-08-04
    • 1970-01-01
    • 2016-03-02
    相关资源
    最近更新 更多