1

I am working on an ASP.NET framework 2.0 application. On a particular page I am providing a link to user. By clicking on this link a window opens with another aspx page. This page actually sends http request to a third-party url which points to a file(like - mirror urls to download file from cloud). The http response is sent back to user on the very first page using response.write from where user click the link.

Now, the problem I am facing is if the file size is low then it works fine. But, if the file is large (i.e., more than 1 GB), then my application waits until whole file is downloaded from the URL. I have tried using response.flush() to send chunk by chunk data to user, but still user is unable to use application because the worker process is busy getting streams of data from third party URL.

Is there any way by which large files can be downloaded asynchronously so that my pop-up window finishes its execution(download will be in progress) and also user can do other activities on application parallely.

Thanks, Suvodeep

1 Answers1

0

Use WebClient to read the remote file. Instead of downloading you can take the Stream from the WebClient. Put that in while() loop and push the bytes from the WebClient stream in the Response stream. On this way, you will be async downloading and uploading at the same time.

HttpRequest example:

private void WriteFileInDownloadDirectly()
{
    //Create a stream for the file
    Stream stream = null;

    //This controls how many bytes to read at a time and send to the client
    int bytesToRead = 10000;

    // Buffer to read bytes in chunk size specified above
    byte[] buffer = new byte[bytesToRead];

    // The number of bytes read
    try
    {
        //Create a WebRequest to get the file
        HttpWebRequest fileReq = (HttpWebRequest)HttpWebRequest.Create("Remote File URL");

        //Create a response for this request
        HttpWebResponse fileResp = (HttpWebResponse)fileReq.GetResponse();

        if (fileReq.ContentLength > 0)
            fileResp.ContentLength = fileReq.ContentLength;

        //Get the Stream returned from the response
        stream = fileResp.GetResponseStream();

        // prepare the response to the client. resp is the client Response
        var resp = HttpContext.Current.Response;

        //Indicate the type of data being sent
        resp.ContentType = "application/octet-stream";

        //Name the file 
        resp.AddHeader("Content-Disposition", $"attachment; filename=\"{ Path.GetFileName("Local File Path - can be fake") }\"");
        resp.AddHeader("Content-Length", fileResp.ContentLength.ToString());

        int length;
        do
        {
            // Verify that the client is connected.
            if (resp.IsClientConnected)
            {
                // Read data into the buffer.
                length = stream.Read(buffer, 0, bytesToRead);

                // and write it out to the response's output stream
                resp.OutputStream.Write(buffer, 0, length);

                // Flush the data
                resp.Flush();

                //Clear the buffer
                buffer = new byte[bytesToRead];
            }
            else
            {
                // cancel the download if client has disconnected
                length = -1;
            }
        } while (length > 0); //Repeat until no data is read
    }
    finally
    {
        if (stream != null)
        {
            //Close the input stream
            stream.Close();
        }
    }
}

WebClient Stream reading:

using (WebClient client = new WebClient())
{
     Stream largeFileStream = client.OpenRead("My Address");
}
  • Ваньо, the above HttpWebRequest example is exactly the same as my current implementation. I am providing an http url to create httpwebrequest. But the problem is it continuously loops through the while loop untill the end of 1 GB file and then main process exits the while loop to end the process. – Suvodeep Roy May 27 '17 at 18:22
  • How do I use Webclient asynchronously so that file can be downloaded parallely. Please suggest. – Suvodeep Roy May 28 '17 at 13:13
  • Updated my answer. That's how you can get the stream from WebClient. Then the logic is the same - while loop and reading chunks. – Vanyo Vanev May 29 '17 at 10:32