Async WebApi Thread.CurrentCulture

Mam własny hostingOWIN hostowaneWeb API projekt zapewniający podstawowe metody REST.

Chcę mieć wielojęzyczne komunikaty o błędach, więc używamRatunek pliki iBaseController to ustawiaThread.CurrentCulture iThread.CurrentUICulture doAkceptuj-język nagłówek żądania.

public override Task<HttpResponseMessage> ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken)
{
    if (controllerContext.Request.Headers.AcceptLanguage != null && 
        controllerContext.Request.Headers.AcceptLanguage.Count > 0)
    {
        string language = controllerContext.Request.Headers.AcceptLanguage.First().Value;
        var culture = CultureInfo.CreateSpecificCulture(language);

        Thread.CurrentThread.CurrentCulture = culture;
        Thread.CurrentThread.CurrentUICulture = culture;
    }

    base.ExecuteAsync(controllerContext, cancellationToken);
}

To wszystko działa dobrze, ale problem pojawia się, gdy robię mójasynchroniczne metody kontrolera.

Kiedy używamoczekiwać w metodzie może być kontynuowany w innym wątku, a więc mójCurrentCulture iCurrentUICulture są zgubieni.

Oto mały przykład, którego użyłem do znalezienia tego problemu.

public async Task<HttpResponseMessage> PostData(MyData data)
{
    Thread currentThread = Thread.CurrentThread;

    await SomeThing();

    if (Thread.CurrentThread.CurrentCulture != currentThread.CurrentCulture)
        Debugger.Break();
}

Nie zawsze włamuję sięDebugger.Break line, ale większość czasu to robię.

Oto przykład, w którym faktycznie używam mojegoPlik zasobów.

public async Task<HttpResponseMessage> PostMyData(MyData data)
{
    //Before this if I'm in the correct thread and have the correct cultures
    if (await this._myDataValidator.Validate(data) == false)
        //However, I might be in another thread here, so I have the wrong cultures
        throw new InvalidMyDataException(); 
}

public class InvalidMyDataException : Exception
{
    public InvalidMyDataException()
        //Here I access my resource file and want to get the error message depending on the current culture, which might be wrong
        : base(ExceptionMessages.InvalidMyData) 
    {

    }
}

Kilka dodatkowych informacji: Mam całą masę wyjątków, takich jak ten, i wszystkie zostają wplątane w zwyczajExceptionFilterAttribute który następnie tworzy odpowiedź.

Dlatego byłoby dużo kodu, aby zawsze ustawiać kulturę tuż przed jej użyciem.

questionAnswers(3)

yourAnswerToTheQuestion