Ich erstelle eine Reihe von von ASP.Net gehosteten WebAPI-Diensten, die eine alte Bibliothek verwenden müssen, die stark von HttpContext.Current abhängig ist. Ich habe Probleme, sicherzustellen, dass der Kontext in allen Methoden erhalten bleibt, die an einem asynchronen Aufruf teilnehmen. Ich habe verschiedene Varianten mit warte/Task.Wait und TaskScheduler.FromCurrentSynchronizationContext() auf den folgenden Code ausprobiert.HttpContext bei asynchronen Verbindungen mit WebAPI (Medium Trust) beibehalten
[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;
}
Ich mag wäre in der Lage sein, um sicherzustellen, dass die Current fr-FR ist, und dass HttpContext.Current ist an jedem Punkt nicht null wo TestOutput genannt wird. Es ist mir nicht gelungen, das für den "In Task" -Aufruf mit allem zu tun, was ich versucht habe. Auch in einigen meiner Tests ändert sich die Thread-ID nicht, was darauf hindeutet, dass ich die Asynchronität der Methode effektiv entfernt habe. Wie kann ich sicherstellen, dass die culture und HttpContext.Current bei jedem Aufruf von TestOutput beibehalten werden, und dass der Code für verschiedene Threads ausgeführt werden kann?
Capturing HttpContext.Current in einer Schließung und dann einfach wieder zu setzen funktioniert nicht für mich, wie ich Medium Trust unterstützen muss, die eine Sicherheitsausnahme beim Aufruf der HttpContext.Current Setter auslösen wird.
Es war mein Verständnis, dass AspNetSynchronizationContext speziell Dinge wie HttpContext beibehalten, wenn auf einem anderen Thread ausgeführt wird. Missverstehe ich oder ist AspNetSynchronizationContext in dieser Situation einfach nicht anwendbar? – ScottS
'AspNetSynchronizationContext' behält' HttpContext' bei, aber nur ein Thread kann sich jeweils in einem Anfragekontext befinden. Sie können den Kontext nicht auf andere Threads setzen, aber "AspNetSynchronizationContext" ist dafür verantwortlich, den Kontext in den Thread-Pool-Thread einzufügen, der die 'async'-Methode wieder aufnimmt, nachdem sie' wartet' hat. –
@StephenCleary - Verzeihen Sie meine Unwissenheit, aber würde "CurrentCulture" über Threads beibehalten, wenn Sie die 'Task.Factory.StartNew()' Methode verwenden - z. 'return await Task.Factory.StartNew (() => {doSomething();};' –