2014-11-07 2 views
2

기존의 자체 호스팅 WCF 서비스를 IIS 호스팅 웹 API로 이식하고 있습니다.웹 API 컨트롤러에서 장기 실행 작업 시작

서비스는 장기 실행 작업을 실행하기위한 것이며 클라이언트 (데스크톱 응용 프로그램)는 작업을 시작하고 결과를 기다리거나 서비스를 끊거나 (전원을 꺼도) 연결을 끊고 나중에 결과를 얻을 수 있습니다. 순간

, WCF 서비스는 접촉이 (세션은 허용되지 않습니다) :

public interface IMyServiceContract 
{ 
    // this initiates the action and returns the action id 
    int StartAction(ActionParams actionParams); 

    // this allows client to query action status (running, completed, faulted) 
    ActionStatus GetActionStatus(int actionId); 

    // this allows client to download action result, if action was completed 
    ActionResult GetActionResult(int actionId); 
} 

ActionParamsActionResult 입력 매개 변수와 결과 값 (그것은 중요하지 않습니다 포함 된 일부 데이터 계약, 무엇 질문의 맥락에서 내부에 있음).

StartAction 메서드는 작업 ID를 만들고 Task.Factory.StartNew을 통해 작업을 시작한 다음 반환합니다. 클라이언트는 주기적으로 서비스를 폴링하여 GetActionStatus 메서드를 호출하고 완료되면 클라이언트는 GetActionResult을 사용하여 결과를 다운로드합니다.

사용자는 작업을 시작하고 클라이언트 응용 프로그램을 실행중인 컴퓨터 인 을 종료 할 수 있지만 나중에 작업 결과를 다운로드 할 수 있습니다.

질문. 웹 API를 사용하여 이러한 작업을 수행하는 방법은 무엇입니까?

저는 SO와 자습서 (asp.net)에서 몇 가지 질문을 읽었지 만 샘플은 매우 유사합니다. 예를 들어, 기다릴 수있는 방법을 구현하고 비동기 API (예 : EF 6)를 호출합니다. 멀리, 내가 알기로는, 이것은 "나중에 연결 해제 및 다운로드"시나리오를 허용하지 않습니다.

또한, 스티븐 클리어 리에서 this 게시물을 알려줍니다

ASP.NET의 원칙 중 하나는 ASP.NET 당신을 제공하는 요청 스레드를 제외하고 (스레드 풀 스레드를 사용하지 않는 이유입니다

, 코스). 더 많은 점은 ASP.NET 응용 프로그램 이 Task.Run을 피해야한다는 것을 의미합니다.

나는 뭔가가 부족합니까?

+0

"누락 된 것이 있습니까?" 예. 장기 실행 프로세스에는 IIS를 사용하지 않아야합니다. IIS (성능 향상 용)는 요청과 직접 관련이없는 모든 스레드를 중지하도록 설계되었습니다. 이는 장기 실행 프로세스 *를 실행할 수 없음을 의미합니다. 이것은 응용 프로그램이 자체 호스팅 서비스였던 원래의 원인 일 가능성이 큽니다. (* 완료 될 수 있지만 매우 어렵습니다. http://weblog.west-wind.com/posts/2013/Oct/02/Use-IIS-Application-Initialization-for-keeping-ASPNET-Apps-alive). – Aron

+0

정직하게 말하면 MQ의 WCF를 사용하는 것이 맞을 것입니다 (MSMQ는 쓰레기라고 경고해야합니다). – Aron

+1

IIS 용 AppFabric 확장을 사용하면 IIS에서 장기 실행 작업을 실행할 수 있습니다. 실제로 IIS에서 호스팅되는 WCF 서비스의 경우 AppFabric을 사용해야합니다. – Uriil

답변

2

장기 실행 작업에는 Hangfire.io이 사용됩니다. Hangfire는 데이터베이스를 사용하여 웹 사이트 (또는 응용 프로그램 풀)가 다시 시작된 경우에도 작업이 실행되도록합니다.

그것은 아주 간단 API 제공 :

BackgroundJob.Enqueue(() => LongRunningTask()); 

을 그리고 그것은 나중에 실행하거나 반복 작업에 대한 작업을 예약 할 수 있습니다 : 자신의 웹 사이트에서

BackgroundJob.Schedule(
    () => LongRunningTask(), 
    TimeSpan.FromDays(7)); 

RecurringJob.AddOrUpdate(
    () => LongRunningTask(), 
    Cron.Daily); 

진술 :

백그라운드 작업이 성공적인 실행에서만 저장소에서 삭제됩니다. 응용 프로그램을 다시 시작하면 갑작스럽게 중단 된 작업이 다시 큐됩니다.
작업이 생성되면 호스트 프로세스가 종료 된 경우에도 적어도 한 번 수행됩니다.

+0

감사합니다. 기대하고 있습니다. – Dennis