异步调用WCF服务并不preserve的CurrentCulture [英] Async call to the WCF service doesn't preserve CurrentCulture

查看:130
本文介绍了异步调用WCF服务并不preserve的CurrentCulture的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据<一个答案href=\"http://stackoverflow.com/questions/14099467/localization-for-async-calls-in-asp-net-webapi\">this问题 异步/的await 调用应该preserve的CurrentCulture。就我而言,当我打电话给我自己的异步方法中,是的CurrentCulture preserved。但是,如果我叫WCF服务的一些方法,的CurrentCulture是不是preserved,它正在改变的东西,看起来像服务器的默认线程的文化。

According to the answer in this question async/await call should preserve CurrentCulture. In my case, when I call my own async methods, the CurrentCulture is preserved. But if I call some method of WCF service, CurrentCulture isn't preserved, it's being changed to something that looks like server's default thread's culture.

我已经看了什么管理线程调用。它发生使code的每一行于单个被管理的线程(ManagedThreadId保持不变)来执行。和CultureInfo的我自己的异步方法的调用后保持不变。但是,当我调用WCF的方法,ManagedTrheadId保持不变,但的CurrentCulture被改变。

I've looked at what managed threads are invoked. It happens so that every line of code was executed on a single managed thread (ManagedThreadId stays the same). And CultureInfo stays the same after a call to my own async method. But when I call a WCF's method, ManagedTrheadId stays the same, but CurrentCulture is changed.

简化code看起来是这样的:

The simplified code looks like this::

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);
}

wcfClient 是汽车的一个实例生成WCF客户端( System.ServiceModel.ClientBase 的继承者)

The wcfClient is an instance of auto generated WCF client (inheritor of System.ServiceModel.ClientBase)

这一切都发生在ASP.NET MVC的Web API(自托管的),我使用Accept-Language头设置的CurrentCulture后访问它,并用它来返回本地化的资源。我可以不沿的CurrentCulture移动,只是通过CultureInfo的每一个方法,但我不喜欢这种方式。

This all happens in ASP.NET MVC Web API (self-hosted), I use Accept-Language header to set CurrentCulture to access it later and use it to return localized resources. I could move along without CurrentCulture and just pass CultureInfo to every method, but I don't like this approach.

为什么CurrentThread的的CurrentCulture就是WCF服务的调用后改变,我自己的异步方法的调用后保持不变?它可以被固定?

Why CurrentThread's CurrentCulture is changed after a call to WCF service and remains the same after a call to my own async method? Can it be "fixed"?

推荐答案

重置文化回到了它以前的等待通常是同步上下文的工作。但是,由于(据我所知),你没有任何同步上下文中,等待不会修改线程文化以任何方式。

Resetting culture back to what it was before the await is usually the job of the synchronization context. But since (as far as I understand it), you don't have any synchronization context, the await won't modify the thread culture in any way.

这意味着,如果你回来在同一线程上后等待,您会看到您设置的文化。但是,如果你继续在不同的线程,你会看到默认的文化(除非别人修改了它的线程太)。

This means that if you're back on the same thread after await, you're going to see the culture that you set. But if you resume on a different thread, you will see the default culture (unless somebody else modified it for that thread too).

当你打算是在同一线程上的的await 后,当没有同步上下文?你保证是同一个线程,如果异步操作同步完成(如您的 GetIntAsync()),因为在这种情况下,该方法只同步后继续在的await 。您还可以继续在同一线程上,如果你是幸运的,但你不能依靠这一点。这可能是不确定的,所以你的code似乎有时工作,有时没有。

When are you going to be on the same thread after an await, when there is no synchronization context? You're guaranteed to be on the same thread if the async operation completes synchronously (like your GetIntAsync()), because in that case, the method just synchronously continues after the await. You can also resume on the same thread if you're lucky, but you can't rely on that. This can be non-deterministic, so your code might seem to work sometimes, and sometimes not.

当你想流文化以你应该做的等待和你没有说会为你同步环境?基本上,你有两个选择:

What you should do when you want to flow culture with awaits and you don't have a synchronization context that does it for you? Basically, you have two options:


  1. 使用自定义awaiter(见斯蒂芬Toub的 WithCulture() ,由Noseratio链接)。这意味着,你需要把它添加到您所有的等待 s其中需要流动的文化,这可能是麻烦的。

  2. 使用,将自动流向文化,每的await 自定义同步上下文。这意味着你可以为每个操作设置方面,只有一次,它会正常工作(类似于ASP.NET什么同步上下文一样)。这可能是从长远来看,更好的解决方案。

  1. Use a custom awaiter (see Stephen Toub's WithCulture(), as linked by Noseratio). This means that you need to add this to all your awaits where you need to flow the culture, which could be cumbersome.
  2. Use a custom synchronization context that will flow the culture automatically for every await. This means you can set up the context only once for each operation and it will work correctly (similarly to what ASP.NET synchronization context does). This is probably the better solution in the long run.

这篇关于异步调用WCF服务并不preserve的CurrentCulture的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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