2012-08-16 10 views
7

Quiero crear un proceso en mi aplicación ASP.NET que active manualmente y envíe un montón de correos electrónicos a mis usuarios. Como este proceso lleva tiempo, estoy creando un nuevo hilo para enviar estos mensajes y evitar que se agote el tiempo de espera en mi aplicación web. (Sé que esto es propenso a errores en caso de que el grupo de aplicaciones se recicle o haya una excepción no controlada en la aplicación, pero ese es otro tema).ASP.NET MVC: vista de representación de excepción en un nuevo hilo

Para que estoy haciendo algo como esto:

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

dentro del proceso de larga duración que estoy tratando de hacer que la vista para el correo electrónico HTML y enviarlo. De esta manera:

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

Ahora, sé que mi método RenderView funciona muy bien desde que lo uso para hacer vistas de correo electrónico en otros lugares. El problema es cuando trato de ejecutarlo en un nuevo hilo como lo hago aquí. Este es mi método 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(); 
     } 
    } 

El error que estoy recibiendo es:

Value does not fall within the expected range. 

Cuando el método se llama viewResult.View.Render.

Supongo que esto tiene que ver con el hecho de que el contexto del controlador ya no es válido en el nuevo hilo, pero no estoy seguro.

Entonces, ¿cuál es la mejor manera de abordar esto? ¿Qué alternativas tengo?

Gracias

Respuesta

5

que supongo que esto tiene que ver con el hecho de que el contexto controlador ya no es válida en el nuevo hilo, pero no estoy seguro.

Precisamente.

Entonces, ¿cuál es la mejor manera de abordar esto?

Envíe correos electrónicos de otro proceso, no su aplicación ASP.NET MVC.

¿Qué alternativas tengo?

Una posibilidad es utilizar 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); 
    } 
} 

También puede pago y envío MvcMailer y enviar el correo electrónico de forma asíncrona (echar un vistazo a la sección Send Email Asynchronously del paso guía paso a).

+1

Parece que el principal problema con el uso de RazorEngine es que no tiene acceso a la resolución HtmlHelper y la plantilla parcial de MVC sin tener que hacer las suyas propias. – crush

Cuestiones relacionadas