2014-09-14 5 views
0

콘솔 응용 프로그램에서 작동하는 파일을 다운로드하는 클래스가 있으며 이제는 webapi 프로젝트에서이 파일을 사용하고 싶습니다. ApiController의 WebClient.DownloadFileAsync가 이벤트를 트리거하지 않습니다.

내가하지만 아닌 ApiController 내부, 콘솔 프로그램에서 작동

WebClient wc = new WebClient(); 
bool downloadFinished = false; 

wc.DownloadProgressChanged += (s, e) => 
{ 
    ProgressChanged(e.BytesReceived, e.TotalBytesToReceive, e.ProgressPercentage); 
}; 
wc.DownloadFileCompleted += (s, e) => 
{ 
    downloadFinished = true; 
}; 

wc.DownloadFileAsync(new Uri(fileUrl), Path.Combine(DOWNLOADFOLDERTEMP, FileName)); 

while (!downloadFinished) 
{ 
    System.Threading.Thread.Sleep(250); 
} 

을 사용하여 파일을 다운로드합니다. 파일을 다운로드하지만 진행 및 완료된 이벤트는 결코 트리거되지 않으므로 무한 루프가 발생합니다.

ApiController에서 호출 될 때 WebClient 트리거 이벤트를 어떻게 만듭니 까?

답변

0

WebClient은 이벤트를 게시하기 위해 현재 SynchronizationContext을 사용합니다. 바쁜 대기로 현재 스레드를 해제하지 않습니다. 비동기 적으로 다운로드를 수행하는 이유와 결과를 기다리는 이유를 모르겠습니다. 이것이 무슨 소용입니까? 동기식 API 만 사용하십시오.

적어도 스핀 대기하지 마십시오. 대기 루프를 제거하려면 WebAPI의 IO에 대한 비동기 지원을 사용하십시오. 비동기를 사용하고 기다립니다. 웹에서 WebClient으로 그 작업을 수행하는 방법을 확인할 수 있습니다.

downloadFinished의 사용은 스레드로부터 안전하지 않습니다. 하지만 어쨌든 그런 변수는 필요 없습니다.

+0

WebClient 동기식 DownloadFile은 진행 상황을보고하지 않기 때문에 DownloadFileAsync를 사용하고 있습니다. – elch

+0

@elch 알겠습니다. 그런 다음 폴링 루프를 없애고 이벤트를 사용하거나 TaskCompletionSource로 기다려야합니다. – usr

+0

이벤트를 사용하면 동일한 교착 상태 문제가 발생합니다. WebClient를 호출하여 동기화 컨텍스트를 억제하면이를 해결할 수 있습니다. 이와 같은 문제는 없지만 비동기 코드는 침입 적입니다. – usr

관련 문제