10

ASP.NET アプリケーションで手動でトリガーするプロセスを作成し、ユーザーに多数の電子メールを送信したいと考えています。このプロセスには時間がかかるため、これらのメッセージを送信し、Web アプリでタイムアウトが発生しないようにするための新しいスレッドを作成しています。(アプリ プールがリサイクルされた場合、またはアプリに未処理の例外がある場合、これはエラーが発生しやすいことはわかっていますが、それは別の主題です)。

そのために、私は次のようなことをしています:

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

長時間実行されるプロセス内で、HTML メールのビューをレンダリングして送信しようとしています。このような:

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

これで、RenderView メソッドを使用して他の場所で電子メール ビューをレンダリングするため、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();
        }
    }

私が得ているエラーは次のとおりです。

Value does not fall within the expected range.

viewResult.View.Render メソッドが呼び出されたとき。

これは、コントローラーのコンテキストが新しいスレッドで有効でなくなったことに関係していると推測していますが、よくわかりません。

それで、これにアプローチする最良の方法は何ですか?どのような代替手段がありますか?

ありがとう

4

1 に答える 1

6

これは、コントローラーのコンテキストが新しいスレッドで有効でなくなったことに関係していると推測していますが、よくわかりません。

正確に。

それで、これにアプローチする最良の方法は何ですか?

ASP.NET MVC アプリケーションではなく、別のプロセスから電子メールを送信します。

どのような代替手段がありますか?

1つの可能性は、使用すること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ステップバイステップ ガイドのセクションを参照してください)。

于 2012-08-17T05:15:15.833 に答える