Wait until file is downloaded from URL via webClient

10,299

Try to use DownloadFile instead of DownloadFileAsync, as you do in Edit 1, like this:

string filename=Path.Combine(TempDirectory, PSFileName);
using (WebClient webClient = new WebClient())
                {
                    // nastaveni ze webClient ma pouzit Windows Authentication
                    webClient.UseDefaultCredentials = true;    
                    // spusteni stahovani
                    webClient.DownloadFile(new Uri("http://czprga2001/Logio_ZelenyKyblik/Export.ashx"), filename);
                }
ExcelToCsv(filename);  //No need to create the event handler if it is not async

From your example it seems that you do not need asynchronous download, so use synchronous download and avoid possible related problems like here.

Also use Path.Combine to combine parts of a path like folder and filename.

There is also a chance that it is locked by something else, use Sysinternals Process Explorer's Find DLL or Handle function to check it.

Use local disk to store downloaded file to prevent problems with network.

Share:
10,299
Muflix
Author by

Muflix

Updated on June 28, 2022

Comments

  • Muflix
    Muflix almost 2 years

    I have struggle with downloading few MB excel file from URL and then work with it. Im using VS2010 so i cant use await keyword. My code follows:

    using (WebClient webClient = new WebClient())
                    {
                        // setting Windows Authentication
                        webClient.UseDefaultCredentials = true;
                        // event fired ExcelToCsv after file is downloaded
                        webClient.DownloadFileCompleted += (sender, e) => ExcelToCsv(fileName);
                        // start download
                        webClient.DownloadFileAsync(new Uri("http://serverx/something/Export.ashx"), exportPath);
                    }
    

    The line in ExcelToCsv() method

    using (FileStream stream = new FileStream(filePath, FileMode.Open))
    

    Throws me an error:

    System.IO.IOException: The process cannot access the file because it is being used by another process.

    I tried webClient.DownloadFile() only without an event but it throws same error. Same error is throwed if i do not dispose too. What can i do ?

    Temporary workaround may be Sleep() method but its not bullet proof.

    Thank you

    EDIT: I tried second approach with standard handling but i have mistake in the code

      using (WebClient webClient = new WebClient())
                    {
                        // nastaveni ze webClient ma pouzit Windows Authentication
                        webClient.UseDefaultCredentials = true;
                        // <--- I HAVE CONVERT ASYNC ERROR IN THIS LINE
                        webClient.DownloadFileCompleted += new DownloadDataCompletedEventHandler(HandleDownloadDataCompleted);
    
                        // spusteni stahovani
                        webClient.DownloadFile(new Uri("http://czprga2001/Logio_ZelenyKyblik/Export.ashx"), TempDirectory + PSFileName);
                    }
    
    public delegate void DownloadDataCompletedEventHandler(string fileName);
            public event DownloadDataCompletedEventHandler DownloadDataCompleted;
            static void HandleDownloadDataCompleted(string fileName)
            { 
                ExcelToCsv(fileName);
            }
    

    EDIT: approach 3 I tried this code

    while (true)
                    {
                        if (isFileLocked(downloadedFile))
                        {
                            System.Threading.Thread.Sleep(5000); //wait 5s
                            ExcelToCsv(fileName);
                            break;
                        }
                    }
    

    and it seems that it is never accessible :/ I dont get it.