i want realize a big file upload progress demo,but below code can't working normal. if remove the code "await Task.Delay(1)" in ProgressableStreamContent class,and id "mybar" element not refresh UI. if add "await Task.Delay(1)" ,it's work normal.can refresh UI,show progress. why? Has anyone encountered this problem? Can you help me with this? Thank you.
<p>
<InputFile OnChange="@OnInputFileChange" />
</p>
<div>
<p>File Size:@totalSize @progressPercent % </p>
@{
var progressWidthStyle = progressPercent + "%";
}
<div class="progress">
<div id="mybar" class="progress-bar" role="progressbar" style="width:@progressWidthStyle" area-valuenow="@progressPercent" aria-minvalue="0" aria-maxvalue="100"></div>
</div>
</div>
private CancellationTokenSource cancelation;
public long totalSize = 0;
public int progressPercent = 0;
private string _fileName = "";
private async Task OnInputFileChange(InputFileChangeEventArgs e)
{
IBrowserFile imageFile = e.File;
totalSize = imageFile.Size;
var buffer = new byte[totalSize];
await imageFile.OpenReadStream(512000*1000).ReadAsync(buffer);
var content = new MultipartFormDataContent { { new ByteArrayContent(buffer), "\"upload\"", e.File.Name } };
var progressContent = new ProgressableStreamContent(content, 10240,
(sent, total) =>
{
progressPercent = (int)(sent * 100 / total);
Console.WriteLine("Uploading {0}%", progressPercent);
StateHasChanged();
});
var repsone = await client.PostAsync("http://localhost:5000/Home/Upload", progressContent);
var taskStr = await repsone.Content.ReadAsStringAsync();
Console.WriteLine("taskStr=" + taskStr);
}
public class ProgressableStreamContent : HttpContent
{
/// <summary>
/// Lets keep buffer of 20kb
/// </summary>
private HttpContent content;
private int bufferSize;
//private bool contentConsumed;
private Action<long, long> 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 async Task SerializeToStreamAsync(Stream stream, TransportContext context)
{
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);
await Task.Delay(1);
//System.Diagnostics.Debug.WriteLine($"Bytes sent {uploaded} of {size}");
await stream.WriteAsync(buffer, 0, length);
}
}
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);
}
}