2010-12-06 11 views
2

최근에 HttpAsyncHandler를 사용하여 긴 폴링 서비스를 만들었습니다. 개발하는 동안 그것은 반복적으로 긴 폴링없이 AsyncResult 객체를 여러 번 재사용 할 수있는 "나"가 될 수 있었다. 가능한 경우 AsyncResult를 다시 작성하거나 다시 사용하여 푸시 기술을 "시뮬레이션"할 수 있습니다 (첫 번째 요청을 구독 요청 인 것처럼 처리).AsynchResult Object를 재 구축하여 푸시 기술을 시뮬레이션 할 수 있습니까?

물론 첫 번째 호출은 훌륭하지만 후속 호출에서는 "개체의 인스턴스에 설정되지 않은 개체"를 계속 제공합니다. 특정 객체가 정적이어서 "완료"되면 재사용하거나 검색 할 수 없기 때문에 "짐작"하고 있습니다 (어떤 통찰력이라도 굉장 할 것입니다!).

그래서 질문은

...

는 동적으로 이전 콜백에서 새로운 콜백을 구축 할 수 있습니까?

는 초기 "가입"프로세스는 다음과 같이 진행됩니다

다음
private void MainLoop() 
{ 
    while (true) 
    { 
     if (_subscribers.Count == 0) 
     { 
      if (_messages.Count == max) 
       _messages.Clear(); 
     } 
     else 
     { 
      if (_messages.Count > 0) 
      { 
       Message message = _messages.Dequeue(); 

       foreach (AsyncResult request in _subscribers.ToArray()) 
       { 
        if(request.ProcessRequest(message)); 
         _subscribers.Remove(request); 
       } 
      } 
     } 

     Thread.Sleep(500); 
    } 
} 

이의 예입니다

다음
public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData) 
{ 
    Guid id = new Guid(context.Request["Key"]); 
    AsyncResult request = new AsyncResult(cb, context, id); 
    Service.Singleton.Subscribe(request); 

    return request; 
} 

는 서비스가 무엇의 예입니다 AsyncResult.ProcessRequest() 호출이 수행하는 작업 :

public bool ProcessRequest(Message message) 
{ 
    try 
    { 
     this.Response = DoSomethingUseful(message); 
     this.Response.SessionValid = true; 
    } 
    catch (Exception ex) 
    { 
     this.Response = new Response(); 
     this.Response.SessionValid = false; 
    } 

    this.IsCompleted = true; 
    _asyncCallback(this); 

    return this.IsCompleted; 
} 

SO ... 이런 일이 가능한 것입니까?
나는 문자 그대로 이것을 시도해 보았지만 작동하지 않았다. 그러나 가능한 것 같아?

AsyncResult newRequest = new AsyncResult(request.cb, request.context, request.id); 

if(request.ProcessRequest(message)) 
{ 
    _subscribers.Remove(request); 
    Subscribers.Add(newRequest); 
} 

답변

4

IAsyncResult 구현은 certain invariants을 충족해야하며 그 중 하나는 한 번만 완료 될 수 있다는 것입니다. 사용중인 AsyncResult은 식별 할 수 없지만 Richter's famous version 인 경우 해당 불변 값을 유지합니다.

event-based asynchronous pattern 구현시 문제가 발생하지 않으려면 최상의 푸시 기반 시스템 인 Microsoft Rx이 가장 좋습니다.

+0

멋진 의견! –

0


내가 IHttpAsyncHandler 인터페이스 및 사용에 완전히 익숙하지 말함으로써 나에게 처음으로 서문을 보자.

일반적으로 비동기 프로그래밍 모델을 사용할 때 각 AsyncResult는 특정 비동기 메서드 호출을 나타내며 재사용하면 안됩니다. BeginProcessing (콜백 메소드)보다 RegisterEvent (콜백) 메소드를 더 많이 찾고있는 것처럼 보입니다. 따라서이 기능을 사용할 수 있다고하더라도 디자인은 비동기 프로그래밍 모범 사례 (IMHO)에 의해 유지되지 않습니다.

요청/응답을 기반으로하는 http를 사용하고 있기 때문에 한 요청에 대해 여러 응답을 푸시 할 수 없을 것으로 보이며 어떻게 든 해킹 할 수 있다고해도 클라이언트는 결국 당신이 가고있는 것에 문제가 될 수있는 답변이 없기 때문에 타임 아웃을하십시오.

Remoting에서는 원격 이벤트에 등록 할 수 있으며 WCF는이 옵션이있는 경우 "밀어 넣기 기술"을 사용할 수있는 이중 계약을 지원합니다.

행운을 비네.

+0

정말 고마워요! –

관련 문제