【问题标题】:Asynchrony and thread culture异步和线程文化
【发布时间】:2015-03-29 01:54:59
【问题描述】:

我有一个 MVC 应用程序,我在其中覆盖了基本控制器的 OnActionExecuting() 方法来设置我的线程文化:

protected override void OnActionExecuting(ActionExecutingContext filterContext) {
    var langCode = GetLangCode();
    Thread.CurrentThread.CurrentUICulture = new CultureInfo(langCode);
    Thread.CurrentThread.CurrentCulture = new CultureInfo(langCode);
}

随着我开始更多地异步编程,我很好奇如果我们将已修改文化的线程返回到线程池,并在异步任务完成时分派一个新线程,文化是如何保持的?有什么我应该注意的问题吗?

【问题讨论】:

  • 该线程处理的下一个请求不会也通过OnActionExecuting 进行吗?
  • @LasseV.Karlsen 每个请求都应该执行OnActionExecuting,但是每个请求不能由多个线程来服务吗?如果在我的数据访问层中我使用异步模型与数据库进行通信,我能否在请求过程中获得两个单独的线程,一个在文化已被修改的地方,另一个在没有被修改的地方?
  • 这似乎是可能的,对此了解不够,抱歉。您是否有机会使用 .NET 4.5?如果是这样,请查看CultureInfo.DefaultThreadCurrentCulture

标签: c# asp.net-mvc async-await


【解决方案1】:

简而言之,是的,ASP.NET 被配置为通过SynchronizationContext 在您的异步操作中传递文化等内容。你可以在 MSDN 上阅读一些关于它是如何工作的:https://msdn.microsoft.com/en-us/magazine/gg598924.aspx

您可以在这个 SO 问题上了解一些与身份相关的问题:Using ASP.NET Web API, my ExecutionContext isn't flowing in async actions

【讨论】:

    【解决方案2】:

    一个主要的问题可能是使用await task.ConfigureAwait(false) 模式,它经常被误用作解决死锁的简单(但错误)补救措施。这样,延续将发生在没有同步上下文的池线程上。在这种情况下,CurrentCulture 不会被流动,因为it doesn't get flowed as a part of ExecutionContext。更糟糕的是,您可能正在使用Task.Run(lambda)(通常不应该在 ASP.NET 应用程序中使用)。 lambda 内的代码不会有正确的CurrentCulture

    否则,AspNetSynchronizationContext 将在 await 延续中正确地流动 CurrentCulture,即使它们发生在不同的线程上。

    【讨论】:

    • @YuvalItzchakov,确实 :) 我刚出生的孩子坚持说我应该和他一起出去玩,而不是 SO :)
    • 恭喜!!绝对是优先级改变者;)
    • @YuvalItzchakov,谢谢!其实比我预想的好玩很多,很开心:)
    猜你喜欢
    • 1970-01-01
    • 2010-09-26
    • 1970-01-01
    • 2011-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-31
    相关资源
    最近更新 更多