如何在运行后台工作线程时使用HTTP上下文?使用MVC邮件程序通过后台线程发送电子邮件时获取异常。例外:参数不能为NULL,HTTP Context。
答案 0 :(得分:1)
我想你的方法需要一个HttpContext但是没有用WebRequest执行。
HttpContext不容易模拟,但并非不可能。尝试使用此代码
分配HttpContext当前 HttpContext.Current = HttpContextHelper.CreateHttpContext(
new HttpRequest("SomePage.asmx", "http://localhost/SomePage.asmx", ""),
new HttpResponse(new StringWriter())
);
HttpContext帮助程序是基于此博客文章http://www.necronet.org/archive/2010/07/28/unit-testing-code-that-uses-httpcontext-current-session.aspx
的帮助程序类public class HttpContextHelper
{
public static HttpContext CreateHttpContext(HttpRequest httpRequest, HttpResponse httpResponse)
{
var httpContext = new HttpContext(httpRequest, httpResponse);
var sessionContainer = new HttpSessionStateContainer("id", new SessionStateItemCollection(),
new HttpStaticObjectsCollection(), 10, true,
HttpCookieMode.AutoDetect,
SessionStateMode.InProc, false);
httpContext.Items["AspSession"] = typeof(HttpSessionState).GetConstructor(
BindingFlags.NonPublic | BindingFlags.Instance,
null, CallingConventions.Standard,
new[] { typeof(HttpSessionStateContainer) },
null)
.Invoke(new object[] { sessionContainer });
return httpContext;
}
}
然而(这很重要):你可能做错了。 BackgroundWorker不适用于MVC,但适用于Windows窗体。请尝试使用TPL。
public ActionResult SendMail()
{
Task.Factory.StartNew(() => MailSender.SendMail(...));
return View(...);
}
甚至更好,使用async:
[AsyncTimeout(150)]
[HandleError(ExceptionType = typeof(TimeoutException),
View = "TimeoutError")]
public async Task<ActionResult> SendMailAsync(CancellationToken cancellationToken )
{
ViewBag.SyncOrAsync = "Asynchronous";
return View("SendMail", await MailSender.SendMailAsync(cancellationToken));
}
在此解释http://www.asp.net/mvc/overview/performance/using-asynchronous-methods-in-aspnet-mvc-4
答案 1 :(得分:1)
当同时使用async / await和HTTPContext时,请始终使用ConfigureAwait(true)允许在原始上下文上继续。例如,请参见下文。您也可以在等待呼叫中调用ConfigureAwait。
var task = new Task(() => book.Bindbook()).ConfigureAwait(true);
task.Start();