2015-01-30 2 views
1

targetFramework = "4.5"에서 targated 된 MVC 4.0 응용 프로그램이 있습니다.비동기 컨트롤러에서 비동기가 작동하지 않습니다. mvc 4.0

기본적으로 파일 처리의 기존 기능을 동기식에서 비동기식으로 변환해야합니다 (대용량 파일 사용자는 다른 작업을 기다릴 필요가 없습니다).

내 코드

[HttpPost] 
     public async Task<ActionResult> FileUpload(HttpPostedFileBase fileUpload)  
{ 

Coreservice objVDS = new Coreservice(); 

    //validate the contents of the file 
model =objVDS. ValidateFileContents(fileUpload); 

// if file is valid start processing asynchronously 
    await Task.Factory.StartNew(() => { objVDS.ProcessValidFile(model); },        CancellationToken.None, 
        TaskCreationOptions.DenyChildAttach, 
        TaskScheduler.FromCurrentSynchronizationContext()); 

return view(); 


} 

은 기본적으로 내가 데이터베이스 작업 (diffrent 프로젝트)를 수행 서비스에있는 비동기 메소드를 호출 할 수 있습니다.

비동기 프로세스가 서비스 메소드의 컨텍스트에 액세스하기를 원합니다. 그 이유는 무엇입니까 TaskScheduler.FromCurrentSynchronizationContext()Task.Factory.StartNew()에 사용하고 있습니다.

서비스 방법은 파일 유형에 따라하는 다음과 같이하고, 두 번째 서비스는

public async task ProcessValidFile(fileProcessDataModel model) 
{ 
employeeWorkedDataservice service =new employeeWorkedDataservice() 

await Task.Factory.StartNew(() => 
             { 
              service .ProcessEmployeeDataFile(model.DataSetToProcess, OriginalFileName, this, model.Source); 
             }, 
             CancellationToken.None, 
             TaskCreationOptions.DenyChildAttach, 
           TaskScheduler.FromCurrentSynchronizationContext());  

} 

ProcessEmployeeDataFile 반환 무효하고 있지 비동기 방식 데이터 작업을 요구 받고있다. 위의 코드를 실행하면 데이터 처리가 완료 될 때까지 컨트롤러로 돌아 가지 않습니다. 나는 여기서 뭔가를 놓치고 있다고 생각한다. 나를 안내하십시오. 어떻게 await 작품을 오해 것 같은

덕분에, 아몰

+0

이미 https://msdn.microsoft.com/en-us/library/hh191443.aspx를 읽은 것으로 간주합니까? – Nzall

+0

예; 내가 놓친 게 있니? – amol

답변

3

보인다.

는 실행중인 동안 다른 일을 할 수는 비동기 적으로 실행할 수 있도록하는 작업에서 실행이 https://msdn.microsoft.com/en-us/library/hh191443.aspx#BKMK_WhatHappensUnderstandinganAsyncMethod

설정 무언가를 읽어보십시오.

결과를 계속하려면 await 키워드를 사용하십시오.

즉시 작업을 생성하면 작업이 해결 될 때까지 즉시 차단됩니다. 효과적으로 동기화됩니다.

처리가 완료 될 때까지 기다리지 않고보기 만하면 언제든지 결과가 나올 때까지 기다리고 싶으므로 await이 전혀 필요하지 않다고 생각됩니다. 귀하의 의견에 대해서는

public task ProcessValidFile(fileProcessDataModel model) 
{ 
    employeeWorkedDataservice service =new employeeWorkedDataservice() 

    return Task.Factory.StartNew(() => 
    { 
     service.ProcessEmployeeDataFile(model.DataSetToProcess, OriginalFileName, this, model.Source); 
    }, 
    CancellationToken.None, 
    TaskCreationOptions.DenyChildAttach, 
    TaskScheduler.FromCurrentSynchronizationContext());  
} 

[HttpPost] 
public ActionResult FileUpload(HttpPostedFileBase fileUpload)  
{ 

    Coreservice objVDS = new Coreservice(); 

    //validate the contents of the file 
    model =objVDS. ValidateFileContents(fileUpload); 

    // if file is valid start processing asynchronously 
    // This returns a task, but if we're not interested in waiting 
    // for its results, we can ignore it. 
    objVDS.ProcessValidFile(model); 

    return view(); 
} 

: 당신이 밀접하게 귀하의 비즈니스 로직을 결합하고 있기 때문에

내가 심각하게 하지 고려하여 서비스 컨트롤러를 전달하거나 서비스를 갖는 세션 컨텍스트에 의존하는 것이 당신의 API 컨트롤러.

컨트롤러에서 필요한 비트를 가져 와서 서비스에 전달하십시오.

+0

답장을 보내 주셔서 감사하지만 view(); 백그라운드에서 파일 업로드가 완료 될 때까지 사용자가보기를 가져 오지 않습니다. ,, CancellationToken.None, TaskCreationOptions.DenyChildAttach, 그것은 Task.Factory.StartNew (() => { service.ProcessEmployeeDataFile (model.DataSetToProcess, OriginalFileName이, model.Source)} 반환과 관련이 있는가 TaskScheduler.FromCurrentSynchronizationContext()); ? – amol

+0

디버깅 중에 나는 실행에 의해 return view()를 볼 수있다; 하지만 사용자는 여전히 차단되어 있습니다. – amol

+0

ok 그래서 CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.FromCurrentSynchronizationContext(); 그리고 이제는 사용자에게 페이지를 보여줍니다. 하지만 지금은 문맥과 세션 값을 새로운 작업에 액세스 할 필요가 없어서 애플리케이션을 깨뜨릴 수 있습니다. 이 경우 컨텍스트와 세션을 유지하는 방법은 무엇입니까? – amol

3

기본적으로 파일 처리의 기존 기능을 동기식에서 비동기식으로 변환해야합니다 (대용량 파일 사용자는 다른 작업을 기다릴 필요가 없습니다).

그건 async이 아닙니다. 내 블로그에 설명대로, async does not change the HTTP protocol.

원하는 것은 ASP.NET에서 "화재 및 잊어 버리기"의 일부 형태입니다. 다른 블로그 게시물 covers a few solutions이 있습니다. Task.Factory.StartNew을 사용하면 이러한 모든 솔루션 중에서 가장 위험합니다.

가장 적합한 (읽기 : 가장 신뢰할 수있는) 솔루션은 적절한 분산 아키텍처를 사용하는 것입니다. ASP.NET 응용 프로그램은 수행 할 작업에 대한 설명을 만들어이를 안정적인 대기열 (예 : MSMQ)에 저장해야합니다. 그런 다음 큐를 처리하는 독립적 인 백엔드 (예 : Win32 서비스)가 있어야합니다. 이것은 복잡하지만 ASP.NET이 의도하지 않은 작업을 수행하도록 시도하는 것보다 오류 발생 가능성이 훨씬 적습니다.

+0

Task.Factory.StartNew (()에서 컨텍스트를 사용할 수 없으므로 Task.Run();으로 변경했습니다. – amol

+0

@amol :'Task.Run' 또한 ASP.NET에서 위험하므로 권장하지 않습니다 –

+0

@ Stephen Cleary Thank You !!! 나는 데모를 위해 그것을 완성해야만했기 때문에 귀하의 의견을 무시했습니다. (기록 수가 적었습니다) .. 나중에 블로그마다 큰 files.Now 스레드 재활용 문제가 발생했습니다. 감사합니다. 감사합니다. 다시 한번. – amol

관련 문제