Dmi*_*nov 6 c# wcf cultureinfo async-await asp.net-web-api
根据这个问题 的答案,async/await
调用应该保留CurrentCulture.就我而言,当我调用自己的异步方法时,将保留CurrentCulture.但是,如果我调用某种WCF服务方法,则不会保留CurrentCulture,它会被更改为看起来像服务器默认线程文化的东西.
我已经了解了调用托管线程的内容.它发生在每个代码行都在一个托管线程上执行(ManagedThreadId保持不变).在调用我自己的异步方法后,CultureInfo保持不变.但是当我调用WCF的方法时,ManagedTrheadId保持不变,但CurrentCulture已更改.
简化的代码如下所示::
private async Task Test()
{
// Befoe this code Thread.CurrentThread.CurrentCulture is "ru-RU", i.e. the default server's culture
// Here we change current thread's culture to some desired culture, e.g. hu-HU
Thread.CurrentThread.CurrentCulture = new CultureInfo("hu-HU");
var intres = await GetIntAsync();
// after with await Thread.CurrentThread.CurrentCulture is still "hu-HU"
var wcfres = await wcfClient.GetResultAsync();
// And here Thread.CurrentThread.CurrentCulture is "ru-RU", i.e. the default server's culture
}
private async Task<int> GetIntAsync()
{
return await Task.FromResult(1);
}
Run Code Online (Sandbox Code Playgroud)
该wcfClient
是汽车的一个实例生成WCF客户端(继承的System.ServiceModel.ClientBase
)
这一切都发生在ASP.NET MVC Web API(自托管)中,我使用Accept-Language标头将CurrentCulture设置为稍后访问它并使用它来返回本地化资源.我可以在没有CurrentCulture的情况下继续前进,只是将CultureInfo传递给每个方法,但我不喜欢这种方法.
为什么在调用WCF服务后更改CurrentThread的CurrentCulture并在调用我自己的异步方法后保持不变?可以"修复"吗?
对于为什么会发生所描述的行为,我没有明确的答案,特别是考虑到整个调用链保持在同一线程上(ManagedThreadId
保持不变)的声明。此外,我关于文化不随执行环境流动的假设AspNetSynchronizationContext
是错误的,事实上,它确实流动。我从@StephenCleary关于尝试的评论中汲取了观点await Task.Delay
,并通过以下小研究验证了这一点:
// GET api/values/5
public async Task<string> Get(int id)
{
// my default culture is en-US
Log("Get, enter");
Thread.CurrentThread.CurrentCulture = new CultureInfo("hu-HU");
Log("Get, before Task.Delay");
await Task.Delay(200);
Thread.Sleep(200);
Log("Get, before Task.Run");
await Task.Run(() => Thread.Sleep(100));
Thread.Sleep(200);
Log("Get, before Task.Yield");
await Task.Yield();
Log("Get, before exit");
return "value";
}
static void Log(string message)
{
var ctx = SynchronizationContext.Current;
Debug.Print("{0}; thread: {1}, context: {2}, culture {3}",
message,
Thread.CurrentThread.ManagedThreadId,
ctx != null ? ctx.GetType().Name : String.Empty,
Thread.CurrentThread.CurrentCulture.Name);
}
Run Code Online (Sandbox Code Playgroud)
输出:
获取、输入;线程:12,上下文:AspNetSynchronizationContext,文化 en-US 获取,在Task.Delay之前;线程:12,上下文:AspNetSynchronizationContext,文化 hu-HU 获取,在Task.Run之前;线程:11,上下文:AspNetSynchronizationContext,文化 hu-HU 获取,在Task.Yield之前;线程:10,上下文:AspNetSynchronizationContext,文化 hu-HU 获取,退出前;线程:11,上下文:AspNetSynchronizationContext,文化 hu-HU
因此,我只能想象里面的某些东西wcfClient.GetResultAsync()
实际上改变了当前线程的文化。解决此问题的方法可能是使用像Stephen Toub 那样的CultureAwaiter
客户服务员。然而,这种症状令人担忧。也许您应该在生成的 WCF 客户端代理代码中搜索“culture”并检查其中发生的情况。尝试逐步执行并找出何时Thread.CurrentThread.CurrentCulture
重置。
归档时间: |
|
查看次数: |
1772 次 |
最近记录: |