我想实现一个大文件上传进度的演示,但是下面的代码不能正常工作。如果删除ProgressableStreamContent类中代码"await Task.Delay(1)“,且id "mybar”元素不刷新UI。如果添加"await Task.Delay(1)“,则它是work normal.can刷新UI,显示进度。为什么?有没有人遇到过这个问题?你能帮我做这个吗?谢谢。
<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);
}
}发布于 2021-05-03 18:18:48
使用Blazor的HttpClient是不可能的,因为它在幕后使用浏览器的fetch-API,目前使用的是这个doesn't support streaming接口。
https://stackoverflow.com/questions/64765560
复制相似问题