Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save christianarielli/76909c1c40e74f5fb73cda34bb0c48e3 to your computer and use it in GitHub Desktop.
Save christianarielli/76909c1c40e74f5fb73cda34bb0c48e3 to your computer and use it in GitHub Desktop.

Revisions

  1. @HirbodBehnam HirbodBehnam created this gist Dec 20, 2019.
    135 changes: 135 additions & 0 deletions UploadWithProgressBar.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,135 @@
    using System;
    using System.IO;
    using System.Net;
    using System.Net.Http;
    using System.Threading.Tasks;

    namespace TestConsole
    {

    // From https://stackoverflow.com/a/41392145/4213397
    internal class ProgressableStreamContent : HttpContent
    {
    /// <summary>
    /// Lets keep buffer of 20kb
    /// </summary>
    private const int defaultBufferSize = 5 * 4096;

    private HttpContent content;

    private int bufferSize;

    //private bool contentConsumed;
    private Action<long, long> progress;

    public ProgressableStreamContent(HttpContent content, Action<long, long> progress) : this(content,
    defaultBufferSize, progress)
    {
    }

    public ProgressableStreamContent(HttpContent content, int bufferSize, Action<long, long> progress)
    {
    if (content == null)
    {
    throw new ArgumentNullException("content");
    }

    if (bufferSize <= 0)
    {
    throw new ArgumentOutOfRangeException("bufferSize");
    }

    this.content = content;
    this.bufferSize = bufferSize;
    this.progress = progress;

    foreach (var h in content.Headers)
    {
    this.Headers.Add(h.Key, h.Value);
    }
    }

    protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)
    {
    return Task.Run(async () =>
    {
    var buffer = new Byte[this.bufferSize];
    long size;
    TryComputeLength(out size);
    var uploaded = 0;


    using (var sinput = await content.ReadAsStreamAsync())
    {
    while (true)
    {
    var length = sinput.Read(buffer, 0, buffer.Length);
    if (length <= 0) break;

    //downloader.Uploaded = uploaded += length;
    uploaded += length;
    progress?.Invoke(uploaded, size);

    //System.Diagnostics.Debug.WriteLine($"Bytes sent {uploaded} of {size}");

    stream.Write(buffer, 0, length);
    stream.Flush();
    }
    }

    stream.Flush();
    });
    }

    protected override bool TryComputeLength(out long length)
    {
    length = content.Headers.ContentLength.GetValueOrDefault();
    return true;
    }

    protected override void Dispose(bool disposing)
    {
    if (disposing)
    {
    content.Dispose();
    }

    base.Dispose(disposing);
    }
    }

    class Program
    {
    static void Main(string[] args)
    {
    upload();
    Console.ReadKey();
    }
    static async void upload()
    {
    using (var client = new HttpClient())
    using (var multiForm = new MultipartFormDataContent())
    {
    client.Timeout = TimeSpan.FromMinutes(5); // You may need this if you are uploading a big file

    var file = new ProgressableStreamContent(new StreamContent(File.OpenRead("C://t.txt"))
    ,(sent,total) => {
    Console.SetCursorPosition(1,0); // Remove last line
    Console.WriteLine ("\bUploading " + ((float)sent/total)*100f);
    });

    multiForm.Add(file, "document", "1.txt"); // Add the file

    multiForm.Add(new StringContent("value"),"key"); // Add some other fields if you like

    var response = await client.PostAsync("https://example.com/upload", multiForm);
    Console.WriteLine(response.StatusCode);
    if (response.StatusCode == HttpStatusCode.OK)
    {
    string res = await response.Content.ReadAsStringAsync();
    Console.WriteLine(res);
    }
    }
    }
    }
    }