简体   繁体   中英

WebClient.DownloadFileAsync in ApiController does not trigger events

I have a class that downloads files that works in a console application and now I want to use it in a webapi project.

To download a file I use

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);
}

Which works in a console program, but not inside an ApiController. It downloads the file, but the progress and completed events never trigger, resulting in an endless loop.

How do I make WebClient trigger events when called in an ApiController?

WebClient uses the current SynchronizationContext to posts its events into. You are not releasing the current thread by busy-waiting. I don't know why you are performing the download asynchronously and then waiting for the result. What good does this do? Just use the synchronous API.

At least, do not spin-wait. Use WebAPI's support for async to IO to get rid of the waiting loop. Use async and await. You'll find on the web how to do that with WebClient .

Your use of downloadFinished is not thread-safe. But you shouldn't need such a variable anyway.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM