Asp.net mvc asp.net mvc 4.5:使HostingEnvironment.QueueBackgroundWorkItem正常工作
我正在尝试在控制器完成工作后完成一些轻量级任务,为此我使用Asp.net mvc asp.net mvc 4.5:使HostingEnvironment.QueueBackgroundWorkItem正常工作,asp.net-mvc,asp.net-mvc-4,task-parallel-library,Asp.net Mvc,Asp.net Mvc 4,Task Parallel Library,我正在尝试在控制器完成工作后完成一些轻量级任务,为此我使用HostingEnvironment.QueueBackgroundWorkItem() 我看到一个奇怪的行为,所以我为此制作了一个人工概念验证应用程序 在我的global.asax.cs中,我有一个很好的函数: public class MvcApplication : HttpApplication { private static NLog.Logger logger = NLog.LogManager.GetCurrent
HostingEnvironment.QueueBackgroundWorkItem()
我看到一个奇怪的行为,所以我为此制作了一个人工概念验证应用程序
在我的global.asax.cs
中,我有一个很好的函数:
public class MvcApplication : HttpApplication
{
private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
public static void ContinueWorkOnBackground(Task workItem)
{
workItem.ContinueWith(t =>
{
if (t.IsFaulted)
{
var ex = t.Exception;
logger.Error(ex);
}
});
HostingEnvironment.QueueBackgroundWorkItem(_ => workItem);
}
在我的控制器中,我创建了一个工作项,并将其抛出:
public ActionResult About()
{
logger.Info("About");
ViewBag.Message = "Your application description page.";
MvcApplication.ContinueWorkOnBackground(TestWorkItem());
return View();
}
private async Task TestWorkItem()
{
logger.Trace("TestWorkItem");
await Task.Delay(500);
logger.Trace("let's fail");
throw new NotImplementedException();
}
我在日志中看到消息“TestWorkItem”,但从未看到“let's fail”,也没有关于错误的消息
我还做了HostingEnvironment.QueueBackgroundWorkItem((Func)(=>workItem))
以确保调用不含糊
如何解决此问题?您的问题是,
TestWorkItem
正在捕获当前请求上下文,并试图在请求上下文的等待后恢复该请求上下文。(我在博客上解释)。由于请求已完成,请求上下文在尝试恢复时不再存在
最好的解决方法是允许QueueBackgroundWorkItem
在请求上下文之外执行代码。因此,首先将助手方法更改为使用Func
而不是任务
:
public static void ContinueWorkOnBackground(Func<Task> workItem)
{
HostingEnvironment.QueueBackgroundWorkItem(async _ =>
{
try
{
await workItem();
}
catch (Exception ex)
{
logger.Error(ex);
}
});
}
NLog生存期是否以任何方式与请求相关联?另一方面,当wait
可用时,最好不要使用ContinueWith
。NLog在那里。我可以打开主页,看到它附加到日志中。在阅读了有关捕获上下文的内容后,我立即理解了它(但在几个小时之前,我在玩代码时未能理解)。谢谢
public ActionResult About()
{
logger.Info("About");
ViewBag.Message = "Your application description page.";
MvcApplication.ContinueWorkOnBackground(() => TestWorkItem());
return View();
}