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.