全球化和WCF:将线程返回到ThreadPool时,自定义设置的CurrentCulture未设置为默认值 [英] Globalization and WCF: custom set CurrentCulture is not set back to default when thread is returned to the ThreadPool

查看:47
本文介绍了全球化和WCF:将线程返回到ThreadPool时,自定义设置的CurrentCulture未设置为默认值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,

我注意到WCF ThreadPool的异常行为.如果运行Web应用程序在 集成模式 AspNet兼容模式 关闭 ,然后观察到WCF ThreadPool的异常行为.

I noticed strange behavior of WCF ThreadPool. If web application runs in Integrated Mode and AspNet compatibility mode is turned off, then I observe unexpected behavior of WCF ThreadPool.

我注意到在一个线程上设置了自定义文化(处理WCF请求时),则不会在线程返回TheadPool时恢复为默认值.奇怪的 可以观察到副作用-可能发生的情况是,对WCF服务的后续请求将由修改了CurrentCulture的线程处理.事实证明,应该无状态的Web服务不是无状态的,因为CurrentCulture可以 被先前的网络服务呼叫所污染.

I noticed that custom culture that was set on one thread (when processing WCF request), is not changed back to default when thread is returned to the TheadPool. Strange side effect can be observed - it could happen that subsequent request to WCF service will be processed by a thread that has modified CurrentCulture. It turns out that web services that should be stateless are not stateless because CurrentCulture can be contaminated by previous web-service calls.

有趣的是-如果您在以下位置运行Web应用程序,则不会发生此问题 经典模式或启用A spNet兼容模式 .

What is interesting - the problem will not occur if you run web application in Classic Mode or you enable AspNet compatibility mode. 

有人能解释这种奇怪的行为吗?是错误还是我错过了什么?

此处是可用于重现问题的代码

    [ServiceContract]
    public interface IDiagnosticService
    {
        [OperationContract]
        string GetCurrentThreadCulture();
    }
    [ServiceContract]
    public interface IProcessMessageService
    {
        [OperationContract]
        void LogMessage(string cultureName, string message);
    }
    public class DiagnosticService : IDiagnosticService
    {
        public string GetCurrentThreadCulture()
        {
            return Thread.CurrentThread.CurrentCulture.Name;
        }
    }
    public class ProcessMessage : IProcessMessageService
    {
        public void LogMessage(string cultureName, string message)
        {
            var newCurrentCulture = new CultureInfo(cultureName);
            Thread.CurrentThread.CurrentCulture = newCurrentCulture;
            System.Diagnostics.Debug.WriteLine(message);
        }
    }
        static void Main(string[] args)
        {
            // To reproduce a problem:
            // 1) Assign web application WebApplicationWithTwoServices to Application Pool that works in Integrate Mode
            // 2) Make sure that AspNet compatibility mode is tuned off in Web.Config (WebApplicationWithTwoServices)
            // 3) Use Local IIS Server to host web application WebApplicationWithTwoServices
            string defaultCultureName = CultureInfo.CurrentCulture.Name;
            string testCultureName = defaultCultureName.StartsWith("en") ? "pl" : "en";
            for (; ; )
            {
                string serviceThreadCultureCode;
                using (var diagnosticServiceClient = new DiagnosticServiceClient())
                {
                    serviceThreadCultureCode = diagnosticServiceClient.GetCurrentThreadCulture();
                    if (!serviceThreadCultureCode.Equals(defaultCultureName))
                    {
                        throw new Exception(String.Format("Thread culture contamination! Default culture on the server should be {0} not {1}.", defaultCultureName, testCultureName));
                    }
                }
                using (var processMessageServiceClient = new ProcessMessageServiceClient())
                {
                    processMessageServiceClient.LogMessage(testCultureName, "Hello World");
                }
                Console.Write(String.Format("Default culture on the server is {0}. Thread that was processing web-service request has culture: {1}", 
                    defaultCultureName, 
                    serviceThreadCultureCode));
            }
        }


推荐答案

"

这是预期的.  通常,永远不要设置影响ThreadPool线程的状态,因为您永远不知道线程的生存期.

请注意,这不会 总是发生.  如果您有较大的空闲"线程,则ASP.Net可以释放一些ThreadPool线程并创建新的线程池.时期.  因此,您无法保证何时会发生这种情况.

Note that this will not always happen.  It's possible for ASP.Net to release some of the ThreadPool threads, and create new ones, if you have large "idle" periods.  As such, you have no guarantees of when this would happen.

最好的选择是不要设置线程的文化,但是对ToString等使用重载,它允许您指定特定的区域性.  


这篇关于全球化和WCF:将线程返回到ThreadPool时,自定义设置的CurrentCulture未设置为默认值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆