Tôi đang xây dựng một tập hợp các dịch vụ WebAPI được lưu trữ trên ASP.Net phải sử dụng một thư viện cũ phụ thuộc rất nhiều vào HttpContext.Current. Tôi gặp sự cố khi đảm bảo bối cảnh đó được giữ nguyên trong tất cả các phương thức tham gia vào cuộc gọi không đồng bộ. Tôi đã thử một số biến thể với await/Task.Wait và TaskScheduler.FromCurrentSynchronizationContext() trên đoạn mã dưới đây.Bảo tồn HttpContext khi không đồng bộ với WebAPI (Medium Trust)
[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;
}
Tôi muốn đảm bảo rằng CurrentCulture là fr-FR và HttpContext.Current không phải là null tại mỗi điểm mà TestOutput được gọi. Tôi đã không thành công trong việc làm điều đó cho cuộc gọi "Trong nhiệm vụ" với bất cứ điều gì tôi đã cố gắng. Ngoài ra trong một số id thread thử nghiệm của tôi không bao giờ thay đổi cho thấy rằng tôi đã có hiệu quả loại bỏ asynchronicity của phương pháp. Làm thế nào tôi có thể đảm bảo rằng văn hóa và HttpContext.Current được bảo quản tại mỗi cuộc gọi đến TestOutput, và rằng mã là miễn phí để chạy trên các chủ đề khác nhau?
Chụp HttpContext.Trong quá trình đóng và sau đó chỉ cần thiết lập lại nó sẽ không hoạt động đối với tôi vì tôi cần hỗ trợ Medium Trust, điều này sẽ ném một ngoại lệ bảo mật khi gọi hàm HttpContext.Current setter.
Đó là sự hiểu biết của tôi rằng AspNetSynchronizationContext là đặc biệt để lưu giữ những thứ như HttpContext khi được thực thi trên một chuỗi khác. Tôi có hiểu lầm, hoặc là AspNetSynchronizationContext không áp dụng trong trường hợp này? – ScottS
'AspNetSynchronizationContext' giữ nguyên' HttpContext', nhưng chỉ một luồng có thể nằm trong ngữ cảnh yêu cầu tại một thời điểm. Bạn không thể đặt bối cảnh trên các chủ đề khác, nhưng 'AspNetSynchronizationContext' phụ trách việc đặt ngữ cảnh vào luồng thread thread để tiếp tục phương thức' async' sau khi nó đang chờ đợi. –
@StephenCleary - Hãy tha thứ cho sự thiếu hiểu biết của tôi nhưng sẽ 'CurrentCulture' được bảo toàn qua các chủ đề nếu sử dụng phương thức' Task.Factory.StartNew() '- ví dụ: 'return await Task.Factory.StartNew (() => {doSomething();};' –