Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
513 views
in Technique[技术] by (71.8m points)

asp.net - Preserve HttpContext when going async with WebAPI (Medium Trust)

I am building a set of ASP.Net hosted WebAPI services that must use an old library which depends heavily on HttpContext.Current. I am having trouble ensuring that context is preserved in all the methods that participate in an async call. I have tried several variations with await/Task.Wait and TaskScheduler.FromCurrentSynchronizationContext() on the below code.

    [HttpGet]
    public Task<IEnumerable<string>> ContinueWith()
    {
        Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-FR");  //or another culture that is not the default on your machine
        Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;

        var output = new List<string> { TestOutput("Action start") };

        var task = Task.Factory.StartNew(() =>
            {
                Thread.Sleep(1000);
                return TestOutput("In Task");
            }).ContinueWith(slowString =>
            {
                output.Add(slowString.Result);

                output.Add(TestOutput("Action end"));
                return output as IEnumerable<string>;
            });

        output.Add(TestOutput("Action Mid"));

        return task;
    }

    private string TestOutput(string label)
    {
        var s = label + " ThreadID: " + Thread.CurrentThread.ManagedThreadId.ToString(CultureInfo.InvariantCulture);
        s += " " + Thread.CurrentThread.CurrentCulture.EnglishName;
        s += HttpContext.Current == null ? " No Context" : " Has Context";
        Debug.WriteLine(s);
        return s;
    }

I would like to be able to ensure that the CurrentCulture is fr-FR, and that HttpContext.Current is not null at each point where TestOutput is called. I have not succeeded in doing that for the "In Task" call with anything I have tried. Also in some of my test thread id never varies suggesting that I have effectively removed the asynchronicity of the method. How can I ensure that the culture and HttpContext.Current are preserved at each call to TestOutput, and that the code is free to run on different threads?

Capturing HttpContext.Current in a closure and then simply setting it again will not work for me as I need to support Medium Trust which will throw a security exception when calling the HttpContext.Current setter.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

A little noticed fact, HttpContext.Current is writable.

var context = HttpContext.Current;
var task = Task.Factory.StartNew(() => {
    HttpContext.Current = context;
    // You may want to set CultureInformation here too.

    return TestOutput("In Task");
});

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...