2010-02-05 32 views
5

Tôi hiện đang phát triển một HttpHandler tùy chỉnh (để nén/kết hợp CSS, nhưng điều đó không quan trọng cho câu hỏi này).Mẫu để sử dụng lại không đồng bộ HttpHandler

Tôi bắt đầu với một HttpHandler đồng bộ hóa có thể tái sử dụng đơn giản như chúng ta đều biết.

Bây giờ tôi đang cố gắng cải thiện nó thành trình xử lý không đồng bộ (vì nó sử dụng chức năng IO và được sử dụng trên một trang web rất bận).

nỗ lực đầu tiên của tôi (và điều này dường như làm việc ok):

Action<HttpContext> asyncProcessRequest; 

public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData) 
{ 
    asyncProcessRequest = new Action<HttpContext>(ProcessRequest); 
    return asyncProcessRequest.BeginInvoke(context, cb, extraData); 
} 

public void EndProcessRequest(IAsyncResult result) 
{ 
    asyncProcessRequest.EndInvoke(result); 
} 

public virtual void ProcessRequest(HttpContext context) 
{ 
    // real work 
} 

Đây là một HttpHandler không thể tái sử dụng (kể từ những gì tôi đọc, IsReusable phải là sai lầm, bởi vì xử lý này có nhà nước (các asyncProcessRequest . trường)

Bây giờ tôi muốn thực hiện tái sử dụng này Vì vậy, suy nghĩ đầu tiên của tôi là tạo ra một từ điển của IAsyncResult/hành động như thế này:.

IDictionary<IAsyncResult, Action<HttpContext>> asyncProcessRequests; 

public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData) 
{ 
    if (asyncProcessRequests == null) 
    { 
     asyncProcessRequests = new Dictionary<IAsyncResult, Action<HttpContext>>(); 
    } 

    var request = new Action<HttpContext>(ProcessRequest); 
    var result = request.BeginInvoke(context, cb, extraData); 
    asyncProcessRequests.Add(result, request); 
    return result; 
} 

public void EndProcessRequest(IAsyncResult result) 
{ 
    Action<HttpContext> action; 
    if (asyncProcessRequests.TryGetValue(result, out action)) 
    { 
     action.EndInvoke(result); 
    } 
} 

đây có phải là một correc t mẫu? hoặc tôi đang đi? Có vẻ như để làm việc (tôi không nhận được bất kỳ lỗi hoặc hành vi kỳ lạ), nhưng trước khi đưa nó vào sản xuất, tôi muốn xác minh với một người có nhiều kinh nghiệm hơn tôi trong việc viết các trình xử lý Http này ..

Cảm ơn bạn trước!

+1

Bạn có chắc chắn thực sự cần phải nén/nén CSS cho mỗi và mọi yêu cầu không? Có lẽ, nó tốt hơn để làm điều này trong quá trình xây dựng/triển khai? –

+0

... và/hoặc đảm bảo rằng nó được lưu trữ đúng cách. – Lucero

+1

bộ nhớ cache của trình duyệt và tệp được xử lý đúng cách. Nhưng câu hỏi này là nhiều hơn về mô hình httphandler async/tái sử dụng ... –

Trả lời

4

Nói chung, đối với mẫu không đồng bộ, bạn nên sử dụng tham số trạng thái mà bạn chuyển vào phương thức BeginXxx làm tham số cuối cùng (bạn gọi nó là extraData).

Vì vậy, bạn có thể muốn tạo lớp trợ giúp giữ (ban đầu) extraData cũng như bất kỳ trạng thái bổ sung nào bạn cần để xử lý yêu cầu kết thúc.

Tuy nhiên, trong trường hợp cụ thể của bạn, tôi tin rằng bạn không tăng tốc bất cứ điều gì với việc sử dụng mẫu không đồng bộ. Trong khi nó hoạt động, về cơ bản nó chỉ bổ sung thêm chi phí, vì bạn đang gọi một đại biểu theo kiểu async, nhưng không có gì ngoài việc gửi một cuộc gọi đến pool thread để xử lý cuộc gọi. Vì vậy, miễn là bạn không có nhiều đại biểu chạy đồng thời thông qua các cuộc gọi async, bạn sẽ không được hưởng lợi nhiều. Vì yêu cầu web đa luồng, tôi không nghĩ rằng điều này sẽ giúp hiệu suất; ngược lại, bạn gặp nguy cơ bị bỏ đói threadpool.

Xử lý async chính xác và hiệu quả không hề dễ dàng. Bạn có thể hưởng lợi từ nó nếu bạn đang làm những thứ không đồng bộ vốn như đọc dữ liệu từ một tệp hoặc kết nối mạng hoặc khi gọi các thành phần bên ngoài hỗ trợ yêu cầu không đồng bộ (chẳng hạn như cuộc gọi dịch vụ web hoặc cơ sở dữ liệu).

+0

Xem thêm http://geekswithblogs.net/SanjayU/archive/2009/01/06/ihttphandler-vs-ihttpasynchandler.aspx – Lucero

+0

Vì vậy, về cơ bản những gì bạn đang nói là, rằng tôi nên gắn bó với một bộ xử lý đồng bộ có thể tái sử dụng? –

+3

Có, nếu bạn chỉ định gọi người được ủy quyền không đồng bộ. Nếu bạn đang thực hiện tệp dài, mạng (bao gồm cả yêu cầu web) hoặc cuộc gọi cơ sở dữ liệu, hãy xem xét triển khai mẫu không đồng bộ, nếu không thì không. Xem thêm http://msdn.microsoft.com/en-us/magazine/cc164128.aspx – Lucero

2

Nếu tôi nhớ chính xác IsReusable chỉ ra cho ASP.NET rằng trình xử lý của bạn không bị hủy sau khi xử lý yêu cầu và cùng một cá thể có thể được sử dụng để xử lý các yêu cầu tiếp theo. I E. một thể hiện của đối tượng xử lý không xử lý nhiều yêu cầu cùng một lúc.

+0

Vì vậy, nó không bị phá hủy (yêu cầu tiếp theo sử dụng cùng một trường hợp). Nhưng nó cũng đảm bảo rằng không có yêu cầu đồng thời được thực hiện trên cùng một ví dụ ... Làm thế nào để asp.net xử lý tải cao sau đó? nó tạo ra nhiều trường hợp hơn?hay nó chờ đợi cho yêu cầu hiện tại được hoàn thành? –

+0

Kể từ khi khởi tạo đối tượng của bạn là rất rẻ, làm cho nó tái sử dụng có thể không có giá trị rắc rối. Điều này có ý nghĩa nếu việc tạo trình xử lý http là tốn kém (ví dụ, nếu nó phải khởi tạo từ một tệp cấu hình hoặc bất kỳ thứ gì). – Lucero

+0

Điểm trong việc sử dụng IHttpAsyncHandler là trả lại luồng được gán cho yêu cầu quay lại hồ bơi luồng (chủ đề là tài nguyên giới hạn). Nếu trình xử lý http của bạn là đối tượng nhẹ và instantiates một cách nhanh chóng tôi nghĩ rằng sẽ không có lợi ích đáng kể trong hoạt động với xử lý có thể tái sử dụng hơn không tái sử dụng. – Yaroslav

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