wulfithewulf
wulfithewulf

Reputation: 57

c# WebClient DownloadFileAsync() does not throw errors

I am successfully downloading files with below code. Since I want them to be downloaded on Application Startup I do not want to block anything -> async.

However I am facing the problem that even when the URI path is complete nonsense it will generate me an empty file, instead of raising the error like stated in msdn

Can anyone help me?

private void DownloadDocuments()
    {
        using (WebClient myWebClient = new WebClient())
        {
            try
            {
                Log("load1");
                myWebClient.DownloadFileAsync(new Uri(documentsUri + documentActivation), documentspath + "\\" + documentActivation);

            }
            catch (WebException)
            {
                Log("Guide Activation Download failed.");
            }
            catch (InvalidOperationException)
            {
                Log("Guide Activation could not be saved.");
            }
        }
        using (WebClient myWebClient = new WebClient())
        { 
            try
            {
                Log("load2");
                myWebClient.DownloadFileAsync(new Uri(documentsUri + documentFloating), documentspath + "\\" + documentFloating);
            }
            catch (WebException)
            {
                Log("Guide Floating Download failed.");
            }
            catch (InvalidOperationException)
            {
                Log("Guide Floating could not be saved.");
            }
        }
        using (WebClient myWebClient = new WebClient())
        {
            try
            {
                Log("load3");
                myWebClient.DownloadFileAsync(new Uri(documentsUri + documentSeat), documentspath + "\\" + documentSeat);
            }
            catch (WebException)
            {
                Log("Guide Seat Download failed.");
            }
            catch (InvalidOperationException)
            {
                Log("Guide Seat could not be saved.");
            }
        }
    }

Upvotes: 1

Views: 1835

Answers (1)

Adam Simon
Adam Simon

Reputation: 2970

WebClient.DownloadFileAsync doesn't throw exceptions on HTTP request failures. You need to subscribe to the DownloadFileCompleted event to get notified of errors.

However, I don't recommend messing with event handler callbacks once we have the task-based async/await feature in C#: WebClient.DownloadFileTaskAsync is much more convenient to use.

With your comment about parallel processing in mind, you can do something like this:

static async Task DownloadDocumentAsync(Uri uri, string fileName)
{
    using (var webClient = new WebClient())
    {
        try
        {
            await webClient.DownloadFileTaskAsync(uri, fileName);
        }
        catch (WebException ex)
        {
            Log($"Downloading {uri} failed. {ex.Message}");
            throw;
        }
        catch (InvalidOperationException)
        {
            Log($"Saving {uri} to {fileName} failed. File is in use.");
            throw;
        }
    }
}

Then your logic at application startup:

var baseUri = new Uri(documentsUri);
var downloadTasks = new[]
{
    DownloadDocumentAsync(new Uri(baseUri, documentActivation), Path.Combine(documentspath, documentActivation)),
    DownloadDocumentAsync(new Uri(baseUri, documentFloating), Path.Combine(documentspath, documentFloating)),
    DownloadDocumentAsync(new Uri(baseUri, documentSeat), Path.Combine(documentspath, documentSeat)),
};

try
{
    Task.WaitAll(downloadTasks);
}
catch (AggregateException)
{
    // handle the case when some of the download tasks failed
}

This way the download tasks executes parallel but Task.WaitAll blocks until all of the tasks are completed. If you want to stay async, you need await Task.WhenAll instead.

Upvotes: 4

Related Questions