0

Is there an easy method to process the loaded data while the download is still running? I do not want to wait for the download to finish to have the whole data on memory or disk before processing. I want to do this because my data is compressed, and I'd like to decompress the byte packets on the run and write them then directly onto disk. So that I never use more memory than one download packet.

I tried to get along with the WebClient class but I didn't find out how to access the last loaded bytes in the DownloadProgressChanged event.

Something like this:

WebClient wc = new WebClient();
Uri uri = new Uri(myURL);
wc.DownloadProgressChanged += wc_DownloadProgressChanged;
wc.DownloadDataAsync(uri);

...

void wc_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
    ProcessData(e.Bytes,e.BytesReceived); //e.Bytes should access the downloaded byte packet
    //but it doesn't exist
}

I figured it already out using libcurl, but I'd like to know if it's possible without using external libraries.

1
  • you can always go down and use HTTP requests or even TCP connections to have a better control, .NET has classes for both options. Commented Feb 2, 2015 at 11:51

1 Answer 1

1

Haven't had the possibility to test it but it could work something like this:

    public void DownloadFileAsync()
    {
        WebClient wc = new WebClient();
        Uri uri = new Uri(myURL);
        //Open Stream from URI
        wc.OpenReadCompleted += new OpenReadCompletedEventHandler(OpenReadCallback);
        wc.OpenReadAsync(uri);
    }


    private static void OpenReadCallback(Object sender, OpenReadCompletedEventArgs e)
    {
        Stream resStream = null;

        try
        {
            resStream = (Stream)e.Result;
            //Your decompression stream Gzip for example
            using (GZipStream compressionStream = new GZipStream(resStream, CompressionMode.Decompress))
            {
                //write gzip stream to file
                using (
                    FileStream outFile = new FileStream(@"c:\mytarget.somefile", FileMode.Create, FileAccess.Write,
                        FileShare.None))
                      compressionStream.CopyTo(outFile);
            }
        }
        finally
        {
            if (resStream != null)
            {
                resStream.Close();
            }
        }
    }
Sign up to request clarification or add additional context in comments.

7 Comments

"The await operator is applied to a task in an asynchronous method to suspend the execution of the method until the awaited task completes." I thought via "await" I have the complete data on memeory, which I didn't want in the first place. Or am I wrong here?
the await operator just waits for the async task to complete. the operation after await is still executed asynchron so you wont have the whole data in memory. Async await just manages the whole scheduling thing, you had to do manually when you used threads.
Okay, thanks! That's already something. But won't I have the whole data still loaded into my stream/memory when the download is complete? Or is the last streamdata freed after each decompression+copying to disk?
Sry the code wont work, just noticed OpenReadAsync wont return a Task<Stream> so you need to register on OpenReadCompleted Event. i will fix the code. To your last comment, you wont have the whole data in memmory unless you read a stream to end in some byte[] or similar actions.
i guess you have to push the CopyTo in the eventhandler into a seperate Thread form the sources of WebClient i guess the event is Scheduled back to the ui thread so the ui thread or the thread calling OpenReadAsync, so this Thread would be blocked while you copy the streams
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.