2012-05-11 18 views
5

Tôi gặp phải một vấn đề lạ ngày hôm nay mà không có ý nghĩa với tôi. Dưới đây là một bản tóm tắt:System.Web.HttpContext.Current nulls chính nó sau khi kiểm tra cho một bộ nhớ cache

Bên trong một phương pháp, tôi kiểm tra cho một mục cache như sau:

private async Task<RatesStatus> getRatesStatusAsync() { 

    //... 

    if (_currentHttpContext != null) { 

     //Here, I am checking for a Cached item 
     var cachedRatesStatusObj = HttpContext.Current.Cache[Constants.RATESSTATUS_CACHE_KEY_NAME]; 
     if (cachedRatesStatusObj != null) 
      return (RatesStatus)cachedRatesStatusObj; 
    } 

    //... 

    cacheRatesStatusObject(ratesStatus); 

    //... 
} 

Ở đây, HttpContext.Current không phải là null như mong đợi trong một ứng dụng ASP.NET. Sau đó, bên trong phương pháp cacheRatesStatusObject, tôi kiểm tra nếu HttpContext.Current là null hay không như sau:

private void cacheRatesStatusObject(RatesStatus ratesStatus) { 

    //... 

    //Seeing if HttpContext.Current is null or not first. 
    //and it is null here... 
    if (HttpContext.Current == null) 
     return; 

    //... 
} 

Và nó là null ở đó. Không biết chuyện gì đang xảy ra ở đây. Có suy nghĩ gì không?

+1

Tôi đã lưu ý rằng phương pháp của bạn được đánh dấu là 'async'. Chỉ cần chắc chắn, bất cứ nơi nào bạn đang gọi phương pháp này, bạn đang làm một 'chờ đợi' một nơi nào đó trước khi 'Response' được gửi lại cho khách hàng và đóng cửa, phải không? Nếu không, nó chỉ có thể là một điều kiện chủng tộc, trong đó 'Response' đang được trả lại và xử lý trước khi đến dòng này, nhưng vẫn có sẵn ở dòng trên. –

+0

@GuthMD Vâng, tôi đã sử dụng 'await' ở đâu đó bên trong phương thức. Đây phải là vấn đề. – tugberk

Trả lời

4

Khi bạn sử dụng async/await, chuỗi xử lý yêu cầu đánh dấu yêu cầu là không đầy đủ và sau đó quay lại ASP.NET thread pool. Khi awaitable hoàn thành sau này, thread khác được gán để chạy phần còn lại của phương thức, tuy nhiên HttpContext không được di chuyển qua các luồng, đó là lý do tại sao bạn nhận tham chiếu null khi gọi phương thức await.

Bạn có thể vượt qua một tài liệu tham khảo của HttpContext với phương pháp chờ đợi, một cái gì đó như thế này:

await cacheRatesStatusObject(HttpContext.Current, ratesStatus); 

Tuy nhiên bạn phải rất cẩn thận đối phó với đồng thời và chủng tộc điều kiện, ví dụ nếu thread chờ đợi khóa một nguồn tài nguyên và một chuỗi yêu cầu khác cố gắng sử dụng nó thì hồ bơi chủ đề của bạn sẽ bùng nổ. Hầu hết mọi người giải quyết điều này bằng cách tạo các đối tượng mới và chuyển chúng vào các chủ đề tối ưu hóa thay vì truyền tham chiếu của HttpContext qua các luồng.

+0

Trên thực tế 'HttpContext.Current' không phải là null sau khi chờ đợi. Nó chỉ là null trong phương thức async. Xem câu hỏi này: http://aspnetwebstack.codeplex.com/discussions/359012 – Aliostad

0

Nó không tự nó.

HttpContext chỉ được lưu trữ theo cách 'tĩnh tĩnh'.

Theo đề xuất của câu trả lời khác, chỉ cần chuyển trường hợp.

+0

Đúng, tôi chỉ biết điều đó. Tôi nhận được một ví dụ của nó trước khi gọi async: 'var httpContext = HttpContext.Current;' sau đó trong quá trình này, tôi làm việc với biến địa phương này. – tugberk

+0

Điều này không có ý nghĩa nhiều. Tại sao ngữ cảnh chủ đề không được sao chép? – Aliostad

+0

@Aliostad: Nó chỉ là cách nó hoạt động. Các chủ đề khác phục vụ các yêu cầu khác sẽ chia sẻ cùng một trạng thái. – leppie

Các vấn đề liên quan