-1

ネットを検索しましたが、HttpWebRequest でファイルをダウンロードしているときに進行状況を取得する方法が見つかりませんでした。このクラスは進歩をサポートしていますか? リンク、チュートリアル、ヒントは大歓迎です。

ありがとう。

PSここにコードがあります...

    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;
        }
    }
4

1 に答える 1

0

同期で応答ストリームをコピーする代わりに、非同期でコピーして、以下の関数でデリゲートをフックしてみてください。ダウンロードされたバイト数で進行状況を取得し、進行状況バーに表示できるはずです....

    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);
    }
于 2013-05-07T08:14:15.487 に答える