WCF服务异步调用不保留CurrentCulture根据这个问题的回答async/await调用应该保留CurrentCulture。在我的例子中,当我调用自己的异步方法时,CurrentCulture被保留。但是,如果我调用某种WCF服务方法,则不会保留CurrentCulture,而是更改为看起来像服务器默认线程文化的内容。我看了看什么叫做托管线程。碰巧每个代码行都在托管线程上执行(ManagedThreadId保持不变)。CultureInfo在调用我自己的异步方法后保持不变。但是当我调用WCF的方法时,ManagedTrheadId保持不变,但CurrentCulture发生了变化。简化的代码如下所示::privateasyncTaskTest(){//在这段代码之前Thread.CurrentThread.CurrentCulture是“ru-RU”,即默认服务器的文化//这里我们将当前线程的文化更改为某种所需的文化,例如hu-HUThread.CurrentThread.CurrentCulture=newCultureInfo("hu-HU");varintres=awaitGetIntAsync();//使用awaitThread.CurrentThread.CurrentCulture后仍然是“hu-HU”varwcfres=awaitwcfClient.GetResultAsync();//这里Thread.CurrentThread.CurrentCulture是“ru-RU”,即默认服务器的文化}privateasyncTaskGetIntAsync(){returnawaitTask.FromResult(1);wcfClient是自动生成的WCF客户端实例(System.ServiceModel.ClientBase继承者)这一切都发生在ASP.NETMVCWebAPI(自托管)中,我使用Accept-Language标头设置CurrentCulture以便稍后访问它并且用它来返回本地化资源。我可以在没有CurrentCulture的情况下继续,只需将CultureInfo传递给每个方法,但我不喜欢这种方法。为什么调用WCF服务后CurrentThread的CurrentCulture变了,调用自己的async方法后还是一样?可以“固定”吗?将文化重置为等待之前的状态通常是同步上下文的工作。但是因为(据我所知),你没有任何同步上下文,await不会以任何方式修改线程文化。这意味着如果您在等待之后返回到同一线程,您将看到您设置的文化。但是,如果您在另一个线程上继续,您将看到默认区域性(除非其他人为该线程修改了它)。在await中,在没有同步上下文的情况下,你什么时候在同一个线程?如果异步操作同步完成(例如GetIntAsync()),它保证在同一个线程上,因为在这种情况下,该方法在等待之后同步继续。运气好的话,同样的帖子也可以继续,但是不能指望。这可能是不确定的,因此您的代码有时似乎有效,有时却无效。当你想要await并且没有同步上下文为你做时你应该怎么做?基本上,您有两种选择:使用自定义等待程序(请参阅由Noseratio链接的StephenToub的WithCulture())。这意味着您需要将此添加到您需要流动文化的所有等待中,这可能很麻烦。使用自定义同步上下文,自动为每个等待流式传输文化。这意味着您只能为每个操作设置一次上下文并且它将起作用(类似于ASP.NET同步上下文所做的)。从长远来看,这可能是一个更好的解决方案。对于为什么会发生所描述的行为,我没有明确的答案,特别是考虑到整个调用链保持在同一线程上的声明(ManagedThreadId保持不变)。此外,我错误地假设文化不随AspNetSynchronizationContext下的执行上下文流动,事实上它确实如此。我从@awaitTask.Delay关于尝试awaitTask.Delay的评论中得到了一点,并通过像这样的一些小研究证实了这一点://GETapi/values/5publicasyncTaskGet(intid){//我的默认文化是zh-CNLog("Get,enter");Thread.CurrentThread.CurrentCulture=newCultureInfo("hu-HU");Log("Get,beforeTask.Delay");等待Task.Delay(200);线程.睡眠(200);Log("Get,beforeTask.Run");awaitTask.Run(()=>Thread.Sleep(100));线程.睡眠(200);Log("Get,beforeTask.Yield");等待Task.Yield();Log("获取,退出前");返回“值”;}staticvoidLog(stringmessage){varctx=SynchronizationContext.Current;Debug.Print("{0};thread:{1},context:{2},culture{3}",message,Thread.CurrentThread.ManagedThreadId,ctx!=null?ctx.GetType().Name:String.空,Thread.CurrentThread.CurrentCulture.Name);}输出:得到,输入;线程:12,上下文:AspNetSynchronizationContext,在Task.Delay之前获取文化en-US;thread:12,context:AspNetSynchronizationContext,culturehu-HUgetbeforeTask.Run;线程:11,上下文:AspNetSynchronizationContext,在Task.Yield之前获取文化hu-HU;thread:10,context:AspNetSynchronizationContext,culturehu-HUgetbeforeexit;thread:11,context:AspNetSynchronizationContext,culturehu-HU所以,我只能想象wcfClient.GetResultAsync()里面的东西实际上改变了当前线程的文化对此的解决方案可能是使用像StephenToub的CultureAwaiter这样的客户端等待程序.然而,这种症状令人担忧。也许您应该在生成的WCF客户端代理代码中搜索“culture”并检查那里发生了什么。尝试单步执行并找出Thread.CurrentThread.CurrentCulture何时重置。以上是C#学习教程:异步调用WCF服务不会保留CurrentCulture共享的所有内容。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场,如涉及侵权,请点击右边联系管理员删除。如需转载请注明出处:
