예제 #1
0
        /// <summary>
        /// Stand-in replacement for HttpClient.GetStringAsync that can report download progress.
        /// </summary>
        /// <param name="client">HttpClient instance</param>
        /// <param name="url">Url of where to download the stream from</param>
        /// <param name="progessReporter">Progress reporter to track progress of the download operation</param>
        /// <returns>String result of the GET request</returns>
        public static async Task <string> DownloadStringWithProgressAsync(this HttpClient client, string url, IProgress <DownloadProgressArgs> progessReporter)
        {
            if (client == null)
            {
                throw new ArgumentNullException(nameof(client), "HttpClient was null");
            }

            if (string.IsNullOrEmpty(url))
            {
                throw new ArgumentNullException(nameof(url), "You must set a URL for the API endpoint");
            }

            if (progessReporter == null)
            {
                throw new ArgumentNullException(nameof(progessReporter), "ProgressReporter was null");
            }

            try
            {
                client.DefaultRequestHeaders.ExpectContinue = false;

                using (var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead))
                    using (var stream = await response.Content.ReadAsStreamAsync())
                        using (var memStream = new MemoryStream())
                        {
                            int receivedBytes = 0;
                            var totalBytes    = Convert.ToInt32(response.Content.Headers.ContentLength);

                            while (true)
                            {
                                var buffer    = new byte[4096];
                                int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);

                                //write the current loop's bytes into the MemoryStream that will be returned
                                await memStream.WriteAsync(buffer, 0, bytesRead);

                                if (bytesRead == 0)
                                {
                                    break;
                                }

                                receivedBytes += bytesRead;

                                var args = new DownloadProgressArgs(receivedBytes, totalBytes);
                                progessReporter.Report(args);
                            }

                            memStream.Position = 0;

                            var stringContent = new StreamReader(memStream);
                            return(stringContent.ReadToEnd());
                        }
            }
            finally
            {
                client.Dispose();
            }
        }
예제 #2
0
 private void Downloader_ProgressChanged(object sender, DownloadProgressArgs e)
 {
     this.Dispatcher.Invoke(new Action(() =>
     {
         this.Progress.Value = e.Progress;
         this.Speed.Text     = string.Format("{0}KB/S", e.Speed / 1024);
         //this.Segments.ItemsSource = e.Segments.Select(p => new SegmentViewModel(p));
     }));
 }
예제 #3
0
    public static async Task <(ArraySegment <byte>, HttpResponseMessage)> DownloadBytesWithProgressAsync
    (
        this HttpClient self,
        Uri uri,
        IProgress <DownloadProgressArgs> progress,
        CancellationToken cts = default
    )
    {
        HttpResponseMessage resp = await self.SendAsync
                                   (
            new HttpRequestMessage {
            Version    = self.DefaultRequestVersion,
            Method     = HttpMethod.Get,
            RequestUri = uri
        },
            HttpCompletionOption.ResponseHeadersRead,
            cts
                                   ).ConfigureAwait(false);

        Debug.Assert(resp is not null);

        resp.EnsureSuccessStatusCode();

        HttpContent content = resp.Content;

        await using Stream stream = await content.ReadAsStreamAsync(cts).ConfigureAwait(false);

        int dl_size = content.Headers.ContentLength is long len
            ? (int)len
            : 65536;

        byte[] pool_buffer = ArrayPool <byte> .Shared.Rent(65536);

        Memory <byte> buf = pool_buffer;

        var memory = new MemoryStream(dl_size);

        var args = new DownloadProgressArgs {
            TotalBytes = (int?)content.Headers.ContentLength,
        };

        progress.Report(args);

        try
        {
            while (true)
            {
                cts.ThrowIfCancellationRequested();

                int read = await stream.ReadAsync(buf, cts).ConfigureAwait(false);

                await memory.WriteAsync(buf[..read], cts).ConfigureAwait(false);
예제 #4
0
        /// <summary>
        /// Helper method to POST binary image data to an API endpoint that expects the data to be accompanied by a parameter
        /// </summary>
        /// <param name="client">HttpClient instance</param>
        /// <param name="imageFile">Valie StorageFile of the image</param>
        /// <param name="url">The API's http or https endpoint</param>
        /// <param name="progessReporter">Progress reporter to track progress of the download operation</param>
        /// <param name="parameterName">The name of the parameter the API expects the image data in</param>
        /// <returns></returns>
        public static async Task <string> SendImageDataWithDownloadProgressAsync(this HttpClient client, StorageFile imageFile, string url, string parameterName, IProgress <DownloadProgressArgs> progessReporter)
        {
            if (client == null)
            {
                throw new ArgumentNullException(nameof(client), "HttpClient was null");
            }

            if (string.IsNullOrEmpty(url))
            {
                throw new ArgumentNullException(nameof(url), "You must set a URL for the the HttpClient");
            }

            if (imageFile == null)
            {
                throw new ArgumentNullException(nameof(imageFile), "You must have a valid StorageFile for this method to work");
            }

            if (string.IsNullOrEmpty(parameterName))
            {
                throw new ArgumentNullException(nameof(parameterName), "You must set a parameter name for the image data");
            }

            if (progessReporter == null)
            {
                throw new ArgumentNullException(nameof(progessReporter), "ProgressReporter was null");
            }

            try
            {
                client.DefaultRequestHeaders.ExpectContinue = false;

                byte[] fileBytes;
                using (var fileStream = await imageFile.OpenStreamForReadAsync())
                {
                    var binaryReader = new BinaryReader(fileStream);
                    fileBytes = binaryReader.ReadBytes((int)fileStream.Length);
                }

                var multipartContent = new MultipartFormDataContent();
                multipartContent.Add(new ByteArrayContent(fileBytes), parameterName);

                using (var response = await client.PostAsync(new Uri(url), multipartContent))
                    using (var stream = await response.Content.ReadAsStreamAsync())
                        using (var memStream = new MemoryStream())
                        {
                            int receivedBytes = 0;
                            var totalBytes    = Convert.ToInt32(response.Content.Headers.ContentLength);

                            while (true)
                            {
                                var buffer    = new byte[4096];
                                int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);

                                //write the current loop's bytes into the MemoryStream that will be returned
                                await memStream.WriteAsync(buffer, 0, bytesRead);

                                if (bytesRead == 0)
                                {
                                    break;
                                }

                                receivedBytes += bytesRead;

                                var args = new DownloadProgressArgs(receivedBytes, receivedBytes);
                                progessReporter.Report(args);

                                Debug.WriteLine($"Progress: {receivedBytes} of {totalBytes} bytes read");
                            }

                            memStream.Position = 0;
                            var stringContent = new StreamReader(memStream);
                            return(stringContent.ReadToEnd());
                        }
            }
            finally
            {
                client.Dispose();
            }
        }
 //This is the event handler to update your UI of progress (there is no need to use UI Dispatcher)
 private void Reporter_ProgressChanged(object sender, DownloadProgressArgs e)
 {
     DownloadProgress = e.PercentComplete;
     IsBusyMessage    = $"downloading {e.PercentComplete.ToString("N2")}%";
 }
예제 #6
0
        /// <summary>
        /// Makes a POST request to an endpoint with image data that reports upload progress, with cancellation support.
        /// </summary>
        /// <param name="client">HttpClient instance</param>
        /// <param name="imageFilePath">Url of where to download the stream from</param>
        /// <param name="apiUrl">Endpoint URL</param>
        /// <param name="parameterName">POST request parameter name</param>
        /// <param name="progessReporter">Args for reporting progress of the download operation</param>
        /// <param name="token">Cancellation token</param>
        /// <returns>String content of the GET request result</returns>
        public static async Task <string> SendImageDataWithDownloadProgressAsync(this HttpClient client, string imageFilePath, string apiUrl, string parameterName, IProgress <DownloadProgressArgs> progessReporter, CancellationToken token)
        {
            if (client == null)
            {
                throw new ArgumentNullException(nameof(client), "The HttpClient was null. You must use a valid HttpClient instance to use this extension method.");
            }

            if (string.IsNullOrEmpty(apiUrl))
            {
                throw new ArgumentNullException(nameof(apiUrl), "You must set a URL for the API endpoint");
            }

            if (imageFilePath == null)
            {
                throw new ArgumentNullException(nameof(imageFilePath), "You must have a valid file path");
            }

            if (string.IsNullOrEmpty(parameterName))
            {
                throw new ArgumentNullException(nameof(parameterName), "You must set a parameter name for the image data");
            }

            if (progessReporter == null)
            {
                throw new ArgumentNullException(nameof(progessReporter), "ProgressReporter was null");
            }

            client.DefaultRequestHeaders.ExpectContinue = false;

            var fileBytes = File.ReadAllBytes(imageFilePath);

            var multipartContent = new MultipartFormDataContent();

            multipartContent.Add(new ByteArrayContent(fileBytes), parameterName);

            using (var response = await client.PostAsync(new Uri(apiUrl), multipartContent, token))
            {
                //Important - this makes it possible to rewind and re-read the stream
                await response.Content.LoadIntoBufferAsync();

                using (var stream = await response.Content.ReadAsStreamAsync())
                {
                    var receivedBytes = 0;
                    var totalBytes    = Convert.ToInt32(response.Content.Headers.ContentLength);

                    while (true)
                    {
                        var buffer    = new byte[4096];
                        var bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length, token);

                        if (bytesRead == 0)
                        {
                            break;
                        }

                        receivedBytes += bytesRead;

                        var args = new DownloadProgressArgs(receivedBytes, receivedBytes);
                        progessReporter.Report(args);

                        Debug.WriteLine($"Progress: {receivedBytes} of {totalBytes} bytes read");
                    }

                    stream.Position = 0;

                    string result;

                    using (var stringContent = new StreamReader(stream))
                    {
                        result = await stringContent.ReadToEndAsync();
                    }

                    return(result);
                }
            }
        }