2010-02-05 5 views
5

현재 CSS를 압축/결합하기위한 사용자 지정 HttpHandler를 개발 중입니다.하지만이 문제는 중요하지 않습니다.재사용 가능한 비동기 HttpHandler 패턴

우리 모두 알고있는 것처럼 간단한 재사용 가능한 = 진정한 동기식 HttpHandler로 시작했습니다.

이제 비동기 처리기 (IO 기능을 사용하고 매우 바쁜 웹 사이트에서 사용됨)로 개선하려고합니다.

내 첫 번째 시도를 (이 확인을 작동하는 것 같다) : 내가 읽은 것과, IsReusable 거짓해야로서이 아닌 재사용 HttpHandler를가 (이다

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 
} 

,이 핸들러합니다 (asyncProcessRequest 상태를 가지고 있기 때문에 . 필드)

는 지금이 재사용을 만들고 싶어 내 첫번째 생각이 같은 IAsyncResult를/액션의 사전 만드는 것이었다 그래서 :.

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); 
    } 
} 

를이는 correc인가 패턴? 또는 나는 떨어져 있냐?

작동하지 않는 것 같습니다 (오류나 이상한 동작이 발생하지는 않습니다).하지만 이것을 제작하기 전에이 HTTP 처리기를 쓰면서 저보다 많은 경험을 가진 사람과 확인하고 싶습니다.

미리 감사드립니다.

+1

각 요청마다 CSS를 압축/압축해야합니까? 어쩌면 빌드/배포 중에이 작업을 수행하는 것이 좋습니다. –

+0

... 그리고/또는 제대로 캐시되는지 확인하십시오. – Lucero

+1

브라우저 및 파일 캐싱이 올바르게 처리됩니다. 하지만이 질문은 httphandler 패턴 async/reusable ... –

답변

4

일반적으로 비동기 패턴의 경우 BeginXxx 메서드에 마지막 매개 변수로 전달한 상태 매개 변수 (extraData)를 사용해야합니다.

(원본) extraData을 포함하는 도우미 클래스와 요청 종료를 처리하는 데 필요한 추가 상태를 만들 수 있습니다.

그러나 특정 경우에 비동기 패턴을 사용하여 어떤 것도 가속화하지 않는다고 생각합니다. 작동하는 동안 비동기식으로 대리자를 호출하기 때문에 기본적으로 오버 헤드가 추가됩니다. 비동기식 호출은 스레드 풀에 대한 호출을 처리하여 호출을 처리합니다. 따라서 비동기 호출을 통해 동시에 여러 대리자를 실행하지 않는 한 많은 이점을 얻지 못할 수 있습니다. 웹 요청은 이미 멀티 스레드되어 있으므로 성능에 도움이되지 않을 것이라고 생각합니다. 반대로, 당신은 쓰레드 풀 기아의 위험에 처하게됩니다.

정확하고 효율적인 비동기 처리는 쉽지 않습니다. 파일 또는 네트워크 연결에서 데이터를 읽거나 비동기 호출을 지원하는 외부 구성 요소 (예 : 웹 서비스 호출 또는 데이터베이스)를 호출 할 때와 같은 본질적으로 비동기적인 작업을 수행하는 경우 이점을 얻을 수 있습니다.

+0

참고 http://geekswithblogs.net/SanjayU/archive/2009/01/06/ihttphandler-vs-ihttpasynchandler.aspx – Lucero

+0

기본적으로 내가 말하는 것은 재사용 가능한 동기 처리기를 사용해야한다는 것입니다. –

+3

예, 비동기 적으로 위임을 호출하려는 경우. 긴 파일, 네트워크 (웹 요청 포함) 또는 데이터베이스 호출을 수행하는 경우 비동기 패턴을 구현하는 것이 좋습니다. 또한 http://msdn.microsoft.com/en-us/magazine/cc164128.aspx – Lucero

2

올바르게 기억한다면 IsReusable은 요청 처리 후 처리기가 파괴되어서는 안되며 같은 인스턴스가 후속 요청을 처리하는 데 사용될 수 있음을 ASP.NET에 알립니다. 나는. 핸들러 오브젝트의 한 인스턴스가 동시에 여러 요청을 처리하지 않습니다.

+0

에 대한 것입니다. 따라서 파괴되지 않습니다 (후속 요청은 동일한 인스턴스를 사용함). 그러나 그것은 또한 같은 인스턴스에 대해 동시 요청이 이루어지지 않는다는 것을 보장합니다 ... asp.net은 어떻게 높은 부하를 처리합니까? 더 많은 인스턴스를 생성합니까?또는 현재 요청이 완료되기를 기다리는가? –

+0

개체 초기화가 매우 저렴하므로 재사용이 가능하지 않을 수 있습니다. 이것은 http 핸들러의 생성이 비용이 많이 든다면 (예를 들어 설정 파일이나 다른 것으로부터 초기화해야하는 경우와 같이) 의미가 있습니다. – Lucero

+0

IHttpAsyncHandler 사용의 요점은 요청에 할당 된 스레드를 다시 스레드 풀로 반환하는 것입니다 (스레드는 제한된 리소스 임). HTTP 처리기가 경량 객체이고 빠르게 인스턴스화하는 경우 재사용 할 수없는 핸들러를 사용하면 성능에 큰 이점이 없을 것이라고 생각합니다. – Yaroslav