【问题标题】:Cannot propagate AspNetSynchronizationContext to TPL task无法将 AspNetSynchronizationContext 传播到 TPL 任务
【发布时间】:2013-01-26 19:41:44
【问题描述】:

我已经阅读了许多文章,为了在 4.5 之前的版本中保留 HttpContext.Current,我们应该传递处理线程的 SynchornizationContext。
这是我正在尝试执行的代码:

TaskScheduler taskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
Task.Factory.StartNew(() => HandleInquiry(currentInquiry, request),
                                                    CancellationToken.None,
                                                    TaskCreationOptions.None, 
                                                    taskScheduler)

当我通过这段代码进行调试时,我可以在任务调度之前确认 taskScheduler 包含 AspNetSynchronizationContext。但是,在 HandleInquiry 方法内(在任务内), SynchronizationContext.Current 为空,而 HttpContext.Current 也为空。我确定我遗漏了一些明显的东西。

【问题讨论】:

  • 为什么在后台任务中需要HttpContext?在我看来,这是一个糟糕的设计。您应该将此任务所需的信息作为参数传递给该任务。
  • 我很想避免它,但我被困在棕地应用程序场景中,我在日志记录任务中使用的库具有 HttpContext.Current 依赖项。我试图避免大量的重写工作。

标签: asp.net multithreading c#-4.0


【解决方案1】:

在后台任务中访问 HttpContext 是一个糟糕的设计。正确的方法是仅将所需的信息作为参数传递。但是,如果您依赖一些在此阶段无法修改的遗留代码和编写错误的代码,您可以将整个 HttpContext 作为参数传递并在任务中重新分配它:

Task.Factory.StartNew(
    state => 
    {
        System.Web.HttpContext.Current = (HttpContext)state;
        HandleInquiry(currentInquiry, request);
    },
    System.Web.HttpContext.Current
);

【讨论】:

  • 这也是我的想法,但我有点不愿意手动执行此操作。我还想知道手动传播 SynchronizationContext.Current 是否有任何价值
【解决方案2】:

您可以添加一个键/值对 key="aspnet:UseTaskFriendlySynchronizationContext" value="true" 在 Web.config 文件的 appSettings 部分中

【讨论】:

  • 我使用的是 .net 4.0 而不是 .net 4.5 ...据我了解,这只适用于 .net 4.5 及更高版本。我记得重新考虑了那个选项,因此不得不接受达林的建议。
猜你喜欢
  • 2019-03-12
  • 1970-01-01
  • 2015-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多