-1

I searched the net but couldn't find any way to get progress while downloading file with HttpWebRequest. Does this class support progress at all? Any link, tutorial, hint would be greatly appreciated.

Thanks.

P.S. Here's the code...

    private static Task<HttpResponse> MakeAsyncRequest(string requestString)
    {
        var request = (HttpWebRequest)WebRequest.Create(requestString);
        Task<WebResponse> requestTask = Task.Factory.FromAsync(
            request.BeginGetResponse,
            asyncResult => request.EndGetResponse(asyncResult),
            null);
        return requestTask.ContinueWith(t => ReadStreamFromResponce(t.Result));
    }

    private static HttpResponse ReadStreamFromResponce(WebResponse result)
    {
        var responseobject = new HttpResponse();
        var response = (HttpWebResponse)result;
        responseobject.StatusCode = (short)response.StatusCode;

        if (!IsSuccess(responseobject.StatusCode))
            return responseobject;

        using (var responseStream = response.GetResponseStream())
        using (var ms = new MemoryStream())
        {
            responseStream.CopyTo(ms);
            responseobject.SetResponse(ms.ToArray());
            return responseobject;
        }
    }
Davita
  • 8,928
  • 14
  • 67
  • 119

1 Answers1

0

Instead of copying response stream in Synchronous, try to copy in Asynchronous and hook the Delegates in the below function, you should be able to get the progress in number of bytes downloaded, display it to progress bar....

    public static void CopyToStreamAsync(this Stream source, Stream destination,
        Action<Stream, Stream, Exception> completed, Action<uint> progress,
        uint bufferSize, uint? maximumDownloadSize, TimeSpan? timeout)
    {
        byte[] buffer = new byte[bufferSize];

        Action<Exception> done = exception =>
            {
                if (completed != null)
                {
                    completed(source, destination, exception);
                }
            };

        int maxDownloadSize = maximumDownloadSize.HasValue
            ? (int)maximumDownloadSize.Value
            : int.MaxValue;
        int bytesDownloaded = 0;
        IAsyncResult asyncResult = source.BeginRead(buffer, 0, new[] { maxDownloadSize, buffer.Length }.Min(), null, null);
        Action<IAsyncResult, bool> endRead = null;
        endRead = (innerAsyncResult, innerIsTimedOut) =>
            {
                try
                {
                    int bytesRead = source.EndRead(innerAsyncResult);
                    if (innerIsTimedOut)
                    {
                        done(new TimeoutException());
                    }

                    int bytesToWrite = new[] { maxDownloadSize - bytesDownloaded, buffer.Length, bytesRead }.Min();
                    destination.Write(buffer, 0, bytesToWrite);
                    bytesDownloaded += bytesToWrite;

                    if (!progress.IsNull() && bytesToWrite > 0)
                    {
                        progress((uint)bytesDownloaded);
                    }

                    if (bytesToWrite == bytesRead && bytesToWrite > 0)
                    {
                        asyncResult = source.BeginRead(buffer, 0, new[] { maxDownloadSize, buffer.Length }.Min(), null, null);
                        // ReSharper disable PossibleNullReferenceException
                        // ReSharper disable AccessToModifiedClosure
                        asyncResult.FromAsync((ia, isTimeout) => endRead(ia, isTimeout), timeout);
                        // ReSharper restore AccessToModifiedClosure
                        // ReSharper restore PossibleNullReferenceException
                    }
                    else
                    {
                        done(null);
                    }
                }
                catch (Exception exc)
                {
                    done(exc);
                }
            };

        asyncResult.FromAsync((ia, isTimeout) => endRead(ia, isTimeout), timeout);
    }
IT Fresher
  • 155
  • 8
  • Thanks, unfortunately I'm using PCL (Portable Class Library) project, where we don't have Begin**** methods. Do you know if it's possible to do something similar in PCL? Thanks – Davita May 07 '13 at 12:07