ASP.NET MVC:新线程中的异常呈现视图 [英] ASP.NET MVC: Exception rendering view in new thread

查看:55
本文介绍了ASP.NET MVC:新线程中的异常呈现视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to create a process in my ASP.NET application that I trigger manually and will send a bunch of emails to my users. Since this process takes a while I am creating a new thread to send these messages and prevent having timeouts in my web app. (I know this is error prone in case the app pool is recycled or there's an unhandled exception in the app, but that's another subject).

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

For that I'm doing something like this:

public ActionResult SendMessages()
{
  Task.Factory.StartNew(() => { SendMessagesLongRunningProcess(); });
  return View();
}

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

inside the long running process I'm trying to render the view for the HTML email and send it. Like this:

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

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

Now, I know that my RenderView method works just fine since I use it to render email views in other places. The problem is when I try to execute it in a new thread as I'm doing here. This is my RenderView method:

    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();
        }
    }

我得到的错误是:

Value does not fall within the expected range.

调用viewResult.View.Render方法时.

When the viewResult.View.Render method is called.

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

I'm guessing this has to do with the fact that the controller context is no longer valid in the new thread, but I'm not sure.

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

So, what is the best way to approach this? What alternatives do I have?

谢谢

推荐答案

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

I'm guessing this has to do with the fact that the controller context is no longer valid in the new thread, but I'm not sure.

精确地

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

So, what is the best way to approach this?

通过其他进程(而不是ASP.NET MVC应用程序)发送电子邮件.

Send emails from another process, not your ASP.NET MVC application.

我有什么选择?

What alternatives do I have?

一种可能性是使用 RazorEngine :

One possibility is to use 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);
    }
}

您还可以签出 MvcMailer ,然后异步发送电子邮件(请查看分步指南的Send Email Asynchronously部分).

You might also checkout MvcMailer and send the email asynchronously (take a look at the Send Email Asynchronously section of the step-by-step-guide).

这篇关于ASP.NET MVC:新线程中的异常呈现视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆