Я думаю, это потому, что я не установил точку останова в методе SerializeToStreamAsyn c. Тогда я не смог увидеть загрузку l oop во время отладки.
Более того, SerializeToStreamAsyn c вызывается HttpClient, когда это требуется.
"SerializeToStream метод скопирует буферизованный поток в сетевой поток, когда это требуется HttpClient "
Проверьте этот пост для другого примера, Даррел Миллер дает дополнительную информацию об этом: Публикация пользовательского типа с HttpClient
Вот мой взгляд:
public partial class SomeView : ContentPage
{
public SomeView()
{
InitializeComponent();
//YOUR CONSTRUCTOR CODE
}
async void StartUploadHandler(object sender, System.EventArgs e)
{
styledProgressBar.Progress = 0;
var fileInfo = (FileInfo)FilesList.SelectedItem;
Progress<UploadBytesProgress> progressReporter = new Progress<UploadBytesProgress>();
progressReporter.ProgressChanged += (s, args) => UpdateProgress((double)(100 * args.PercentComplete) / 100);
fileEndpoint.UploadFiles(fileInfo, progressReporter);
}
void UpdateProgress(double obj)
{
styledProgressBar.Progress = obj;
}
}
Настраиваемый HttpContent:
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);
}
}
Настраиваемая модель выполнения загрузки для репортера:
public class UploadBytesProgress
{
public UploadBytesProgress(string fileName, int bytesSended, int totalBytes)
{
Filename = fileName;
BytesSended = bytesSended;
TotalBytes = totalBytes;
}
public int TotalBytes { get; private set; }
public int BytesSended { get; private set; }
public float PercentComplete { get { return (float)BytesSended / TotalBytes; } }
public string Filename { get; private set; }
public bool IsFinished { get { return BytesSended == TotalBytes; } }
}
И вызов http:
public async Task<string> UploadFiles(FileInfo fileInfo, IProgress<UploadBytesProgress> progessReporter)
{
string res = null;
IAndroidFileHelper androidFileHelper = DependencyService.Get<IAndroidFileHelper>();
using (var client = new HttpClient())
{
using (var multiForm = new MultipartFormDataContent())
{
var bytesFile = androidFileHelper.LoadLocalFile(fileInfo.FullName);
ByteArrayContent byteArrayContent = new ByteArrayContent(bytesFile);
multiForm.Add(byteArrayContent, fileInfo.Name, fileInfo.Name);
var progressContent = new ProgressableStreamContent(multiForm, 4096, (sent, total) =>
{
UploadBytesProgress args = new UploadBytesProgress("SERVEUR URL FOR UPLOAD", (int)sent, (int)total);
progessReporter.Report(args);
});
var uploadServiceBaseAdress = "SERVEUR URL FOR UPLOAD";
var response = await client.PostAsync(uploadServiceBaseAdress, progressContent);
Console.WriteLine(response.StatusCode);
if (response.StatusCode == HttpStatusCode.OK)
{
res = await response.Content.ReadAsStringAsync();
Console.WriteLine(res);
}
else
{
throw new Exception(response.ReasonPhrase);
}
return res;
}
}
}
Каким образом существует другой способ загрузки файла с отчетом о ходе работы:
https://docs.microsoft.com/fr-fr/dotnet/api/system.net.webclient.uploadprogresschanged?view=netframework-4.8
https://forums.xamarin.com/discussion/comment/199958/#Comment_199958
Надеюсь, это поможет некоторым людям, столкнувшимся с той же ситуацией, что и я.