2014-03-28 3 views
0

파일을 다운로드하고 "백그라운드"방식으로 디스크에 저장하는 효율적인 방법은 mvc 컨트롤러에서 현재 실행을 차단하지 않고 있습니까? 현재Syncronous asp.net 컨트롤러에서 Task.Run 사용

I 다음 예제 코드 작업이 : 나는 당신이 (작업자 스레드에서) 서버에 Task.Run를 사용해서는 안 여러 장소를 읽고 그래서이 예제의 경우 궁금 해서요

public ActionResult Index() 
    { 
     InitiateDownload(); 

     var model = GetModel(); 
     return View(model); 
    } 

    private void InitiateDownload() 
    { 
     Task.Run(() => DownloadAndSaveFileAsync()).ConfigureAwait(false); 
    } 
    private async Task DownloadAndSaveFileAsync() 
    { 
     var response = await GetResponse(); 

     using (var fileStream = new FileStream("c:\\file.zip", FileMode.Create, FileAccess.Write, FileShare.None)) 
     { 
      await response.Content.CopyToAsync(fileStream).ConfigureAwait(false); 
     } 
    } 
    public async Task<HttpResponseMessage> GetResponse() 
    { 
     var client = new HttpClient(); 
     client.BaseAddress = new Uri("http://someUrl.com"); 

     return await client.GetAsync("someResourceEndPoint").ConfigureAwait(false); 
    } 

을 (예 : 매초마다 10 건의 요청을받는 경우) 또는 신뢰할 수있는 방법인지, 아니면 그렇게 할 수있는 적절한 방법이있는 경우?

감사 MVC 컨트롤러의 동작의 현재 실행을 중단하지 않고

+0

대기열을 사용하여 안전한 작업을 처리하십시오. – Ramie

답변

2

?

답은 사용자가 의미하는 바에 달려 있습니다. 당신이 다운로드가 진행되는 동안 모델을 구축 할 수 의미하는 경우

, 다음과 같은 단순히 그것을 할 수 있습니다 :

public ActionResult Index() 
{ 
    var task = DownloadAndSaveFileAsync(); 
    var model = GetModel(); 
    await task; 
    return View(model); 
} 

을하지만, 당신은 당신이에 대한 응답을 반환 할 것을 의미하는 경우 클라이언트는 다운로드를 기다리지 않고 훨씬 복잡합니다. I have a blog post that goes into more detail on the subject. 작업이 완료되기 전에 응답을 보내려면 작업이 얼마나 중요한지 결정해야합니다.

다운로드가 필요할 경우 신뢰할 수있는 대기열 (예 : Azure 대기열 또는 MSMQ)에 다운로드 요청을하고 독립 백엔드 (예 : Azure 작업자 역할 또는 Win32 서비스)를 수행해야합니다 실제 다운로드 및 저장 즉, 가끔 누락 다운로드를 처리 할 수있는 시스템이 - -이 완료 다운로드를 갖도록 중요하지 않으면

다음 위 내 블로그 게시물에서 BackgroundTaskManager 유형을 사용할 수 있습니다

private void InitiateDownload() 
{ 
    BackgroundTaskManager.Run(() => DownloadAndSaveFileAsync()); 
} 

나는 또한 당신을 추천합니다 BackgroundTaskManager.Shutdown 취소 토큰을 사용하여 다운로드가 완료되기 전에 AppDomain이 종료 될 때 (예 : 메시지를 이벤트 로그에 기록) 적절한 대응을하십시오.


당신이 선택하든 솔루션, 당신은 비동기 액세스 파일 스트림을 열 DownloadAndSaveFileAsync을 변경해야합니다. 이것은 파일 스트림에 흔히있는 실수입니다. 기본적으로 이들은 동기식입니다.

+0

감사합니다. Stephen BackgroundTaskManager를 사용합니다. 작업이 실패하면 걱정할 필요가 없습니다. "ascynchronous 액세스를 위해 파일 스트림 열기"useAsync : "new FileStream (...)"의 true 매개 변수를 추가한다는 의미입니까? – Vindberg

+0

예, 'useAsync'는 비동기 액세스를 위해 파일을 엽니 다. –

+0

@StephenCleary 어떤 네임 스페이스에서 BackgroundTaskManager를 찾을 수 있습니까? – GibboK