2014-09-29 3 views
1

그래서 나는 (즉시 폴링 엔드 포인트를 반환하고/자원 업데이트 생성, 서버가 작업을 수락)의완료 될 때까지 실행되고 즉시 클라이언트로 돌아갈 작업을 어떻게 생성합니까?

Rick Strahl has a description를 HTTP 202 코드를 사용하여 서버 측 비동기 개념의 증거를 만들려고 해요 일반 ASP.NET에서이 작업을 수행하는 방법. 이 기술은 Response.End를 수행 할 수 있는지에 달려 있으며 코드를 계속 실행합니다. Response 개체는 웹 API 컨트롤러의 컨텍스트에서 사용할 수있는 것조차 보이지 않습니다.

다음 내용이 계획대로 작동하면 http 202를 반환하지 않고 데이터베이스 작업이 완료 될 것이라고 보증하지 않습니다.

//Insert or Update Asych. 
public Task<HttpResponseMessage> Post(bool asynch, [FromBody]DatedValue value) //Insert Value 
{ 
    Guid key = Guid.NewGuid(); 

    //Want this to run to completion, even if response associated with parent thread is done. 
    Task toWait = Task.Factory.StartNew(() => 
    { 
     queue.Add(key, 0); 
     DatedValue justCreated = Insert(value); 
     queue[key] = justCreated.Id; 
    }); 

    //Return address to resource just created. 
    Task<HttpResponseMessage> sender = Task.Factory.StartNew(() => 
    { 
     HttpResponseMessage message = Request.CreateResponse(HttpStatusCode.Accepted); 
     message.Headers.Location = new Uri("/ValueQueue/" + key); 
     return message; 
    }); 

    Task.WaitAll((new[] { toWait, sender })); 

    return sender; 
} 
+1

무엇이 당신의 질문입니까? 나를 시험해? 다른 것을 써주시겠습니까? –

+0

완료까지 실행되는 작업을 생성하고 클라이언트에 응답을 즉시 반환하려면 어떻게해야합니까? 영어로 된 패턴의 짧은 설명은 괜찮을 것이다. 나는 실제로 다중 스레드 코드에 대한 테스트를 신뢰하지 않는다. nunit 호스트는 ASP.NET 호스트처럼 아무것도하지 않는다. – MatthewMartin

+1

코드가 목표를 달성하지 못합니다. 'Task.WaitAll'에 대해 차단하고 있으므로 * 두 작업이 완전히 끝날 때까지는 메소드를 완료 할 수 없습니다. 사물의 소리로 진정으로 원하는 것은 "사후"논리에 대한 화재 및 잊어 버린 (관찰되지 않은) 작업이지만 ASP.NET이 화재 및 잊어 버린 작업을 처리하는 방법과 완료까지 실행되도록 보장 할 것인지 여부입니다 응답이 파견 된 후에도 - 나는 잘 모르겠다. (꽤 나쁜 생각처럼 들린다.) –

답변

3

Task.WaitAll 블록 두 작업이 완료 될 때까지 실행 및 응답이 반환되지 않습니다. 아래처럼 코드를 변경하면 작업이 실행되는 동안 응답을 반환 할 수 있어야합니다.

public HttpResponseMessage Post(bool asynch, [FromBody]DatedValue value) 
{ 
    Guid key = Guid.NewGuid(); 

    Task.Factory.StartNew(() => 
    { 
     queue.Add(key, 0); 
     DatedValue justCreated = Insert(value); 
     queue[key] = justCreated.Id; 
    }); 

    HttpResponseMessage message = Request.CreateResponse(HttpStatusCode.Accepted); 
    message.Headers.Location = new Uri("/ValueQueue/" + key); 
    return message; 
} 

그러나 이와 같은 접근 방식의 문제점을 알고 있어야합니다. IIS에서 Web API를 호스팅하는 경우 작업이 실행되는 동안 작업자 프로세스가 재활용 될 수 있습니다. ASP.NET에 관한 한 이미 응답을 반환 했으므로 ASP.NET은 작업을 완료했습니다. 따라서 IIS가 작업자 프로세스를 재활용하기로 결정한 경우 작업이 실행되는 위치와 관계없이 계속 진행되므로 손상된 데이터로 끝날 수 있습니다.

.NET 4.5.2에서는 QueueBackgroundWorkItem을 사용할 수 있습니다. 읽기 - http://blogs.msdn.com/b/webdev/archive/2014/06/04/queuebackgroundworkitem-to-reliably-schedule-and-run-long-background-process-in-asp-net.aspx.

관련 문제