2012-11-29 2 views
1

현재 일부 타사에서 일부 XML 데이터의 POST를 수행하는 HTTP 처리기를 구현 중입니다. 그런 다음 일부 처리 작업을 수행 할 것입니다. XML을 사용하여 처리하는 데는 약간의 시간이 걸릴 수 있습니다. 일단 POST에서 XML을 꺼내면 데이터를 처리하는 동안 클라이언트와의 연결을 유지할 필요가 없습니다. 클라이언트가 나에게 글을 게시 할 시간을 정할 필요가 없기 때문에 XML을 포착하여 연결 만 허용하려고합니다..NET HTTPHandler에서 연결 해제

이 문제를 쉽게 해결할 수있는 방법이 있습니까? Response.Close()를 사용하면 연결이 제대로 닫히지 않으므로 올바르지 않습니다. Response.End()는 HTTP 처리기를 모두 종료합니다. 처리를 백그라운드 스레드로 던질 수는 있지만 중간에 내 프로세스를 죽일 수있는 AppDomain을 제거 할 수 있으므로 ASP.NET에서 약간 위험 할 수 있다고 들었습니다.

의견을 보내 주시면 감사하겠습니다. 도와 주셔서 감사합니다!

+0

"제대로 닫히지 않아 Response.Close()가 올바르지 않습니다."여기에 어떤 오류가 있습니까? – CodeSpread

+0

http://msdn.microsoft.com/en-us/library/system.web.httpresponse.close.aspx 상태 : "이 메서드는 클라이언트에 대한 연결을 갑자기 종료하고 일반적인 HTTP 요청 처리를위한 것이 아닙니다. 이 메서드는 클라이언트에 리셋 패킷을 보내 서버 나 클라이언트 또는 그 사이의 다른 곳에서 버퍼링 된 응답 데이터를 삭제할 수 있습니다. " 테스트를 통과했을 때 클라이언트에서 HTTP 오류가 발생했습니다. –

+0

올바른 것으로,이를 방지하기 위해 먼저 스트림을 닫은 다음 응답을 닫습니다. – CodeSpread

답변

1

감사합니다 여러분. 다른 사람들은 이것을 해결 방법으로 생각할 수 있습니다.

큐잉은 아마도 "가장 정확한"수단 일 것입니다. 그러나 그것은 내가 현재 가지고있는 것의 꼭대기에있는 것입니다. 할 작정이다. http://haacked.com/archive/2011/10/16/the-dangers-of-implementing-recurring-background-tasks-in-asp-net.aspx

먼저 처리 클래스를 만들고이를 백그라운드 스레드에서 회전시켜 클라이언트에서 XML을 가져온 후 작업을 수행하십시오. 이것은 작업자 스레드가 백그라운드에서 계속 실행되는 동안 연결을 해제합니다.

내 처리 클래스를 IRegisteredObject으로 등록했습니다.완료되면 나는하여 Stop(bool immediate) 내가 일을 처리하고 때 true로 내 _working 변수를 설정하는 방법

public void Stop(bool immediate) 
    { 
     if (!immediate && _working) 
      return;//don't unregister yet, give it some time 

     if(immediate && _working) 
     { 
      //TODO: Log this instance 
     } 
     HostingEnvironment.UnregisterObject(this); 
    } 

하고 해제를 구현했습니다. 드문 경우 AppDomain이 중단되어 작업을 처리하고 중지가 호출되면 먼저 등록을 취소하지 않고 반환합니다. 이것은 내 프로세스가 마무리하는 데 더 많은 시간을줍니다. immediate 플래그를 true로 설정하여 메서드가 두 번째 호출 될 경우 문제를 신속하게 기록한 다음 자체 등록을 취소합니다.

이것이 궁극적 인 해결책은 아닐지 모르지만, 제 목적으로 볼 때 매우 드문 경우가 발생하면 알려주고 데이터 처리시 클라이언트의 연결을 유지하지 않아도됩니다.

2
  1. 수신 된 데이터를 일종의 영구 대기열 (예 : MSMQ)에 저장합니다.
  2. 이탈 처리기.
  3. 다른 응용 프로그램의 대기열에서 데이터를 처리합니다 (예 : Windows 서비스).

이것은 "쉬운 방법"은 아니지만 고객에게 안전하고 빠릅니다.

0

.NET 4.5를 사용하는 경우 HttpTaskAsyncHandler을 확인하십시오. 링크 된 페이지에서

: ASP.NET에서 비동기 처리기를 작성하는

비동기 HTTP 처리기 전통적인 접근 방식은 IHttpAsyncHandler 인터페이스를 구현하는 것입니다. ASP.NET 4.5에서는 HttpTaskAsyncHandler 비동기 기본 유형을 도입하여 비동기 처리기를 작성하기가 훨씬 수월해졌습니다 ( ). HttpTaskAsyncHandler 유형 은 추상적이므로 ProcessRequestAsync 메서드를 재정의해야합니다. 내부적으로 ASP.NET은 ProcessRequestAsync의 반환 코드 (Task 개체)과 ASP.NET 파이프 라인에서 사용하는 이전의 비동기 프로그래밍 모델을 통합 처리합니다. 다음 예는 비동기 HTTP 처리기의 구현의 일환으로 작업을 사용하고 기다리고하는 방법을 보여줍니다 귀하의 의견

public class MyAsyncHandler : HttpTaskAsyncHandler 
{ 
     // ... 

     // ASP.NET automatically takes care of integrating the Task based override 
     // with the ASP.NET pipeline. 
     public override async Task ProcessRequestAsync(HttpContext context) 
     { 
      WebClient wc = new WebClient(); 
      var result = await 
        wc.DownloadStringTaskAsync("http://www.microsoft.com"); 
      // Do something with the result 
     } 
} 
+0

감사합니다. 불행히도 나는 .NET 3.5에 머물러있을 것이다. 나는 여기 간단한 튜토리얼을 사용하여 IHttpAsyncHandler의 빠른 설정을 시도했다. http://msdn.microsoft.com/en-us/library/ms227433(v=vs.85).aspx. 이것은 내가 원하는 것을 얻는 것 같지 않습니다. 연결은 계속 열려 있지만 스레드는 다시 사용하기 위해 스레드 풀로 릴리스됩니다. 내가 이해하는 바에 따르면, 많은 요청을 처리하고 처리 스레드를 풀어야 할 때이다. –

+0

그런 경우, @ Valtasarlll의 대답과 같이 작업을 큐에 넣는 것은 당신이해야 할 일이다. –