ASP.NET MVC:新线程中的异常呈现视图

wil*_*lvv 9 asp.net asp.net-mvc multithreading view

我想在我的ASP.NET应用程序中创建一个手动触发的进程,并将向用户发送一堆电子邮件.由于此过程需要一段时间,因此我创建了一个新线程来发送这些消息并防止在我的Web应用程序中超时.(我知道如果应用程序池被回收或应用程序中存在未处理的异常,这是容易出错的,但这是另一个主题).

为此,我正在做这样的事情:

public ActionResult SendMessages()
{
  Task.Factory.StartNew(() => { SendMessagesLongRunningProcess(); });
  return View();
}
Run Code Online (Sandbox Code Playgroud)

在长时间运行的过程中,我正在尝试呈现HTML电子邮件的视图并发送它.像这样:

private void SendMessagesLongRunningProcess()
{
  var users = GetUsers();
  foreach (var user in users)
  {
    string message = RenderView("EmailMessage", user);
    SendEmail(user.email, message);
  }
}
Run Code Online (Sandbox Code Playgroud)

现在,我知道我的RenderView方法工作正常,因为我用它来渲染其他地方的电子邮件视图.问题是当我尝试在新线程中执行它时,就像我在这里所做的那样.这是我的RenderView方法:

    public string RenderView(string viewName, object model)
    {
        ViewData.Model = model;
        using (var sw = new StringWriter())
        {
            var viewResult = ViewEngines.Engines.FindView(ControllerContext, viewName, null);
            var viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
            viewResult.View.Render(viewContext, sw);
            return sw.GetStringBuilder().ToString();
        }
    }
Run Code Online (Sandbox Code Playgroud)

我得到的错误是:

Value does not fall within the expected range.
Run Code Online (Sandbox Code Playgroud)

调用viewResult.View.Render方法时.

我猜这与控制器上下文在新线程中不再有效的事实有关,但我不确定.

那么,解决这个问题的最佳方法是什么?我有什么替代品?

谢谢

Dar*_*rov 6

我猜这与控制器上下文在新线程中不再有效的事实有关,但我不确定.

正是.

那么,解决这个问题的最佳方法是什么?

从其他进程发送电子邮件,而不是ASP.NET MVC应用程序.

我有什么替代品?

一种可能性是使用RazorEngine:

private void SendMessagesLongRunningProcess()
{
    var users = GetUsers();
    foreach (var user in users)
    {
        string view = Server.MapPath("~/Views/MailTemplates/SomeTemplate.cshtml");
        string template = System.IO.File.ReadAllText(view);
        string message = Razor.Parse(template, user);
        SendEmail(user.email, message);
    }
}
Run Code Online (Sandbox Code Playgroud)

您也可以签出MvcMailer并异步发送电子邮件(请Send Email Asynchronously参阅分步指南部分).