使用 HttpWebRequest 监控上传进度
Monitoring upload progress with HttpWebRequest
我最近编写了一个 C# 函数,它执行多部分表单 post 来上传文件。为了跟踪进度,我将表单数据一次写入 4096 字节的请求流,并在每次写入时回调。但是,似乎在调用 GetResponseAsync() 之前甚至不会发送请求。
如果是这种情况,每写入请求流的 4096 字节的报告是否是上传进度的准确报告?
如果没有,我怎样才能准确报告进度? WebClient 对我来说是不可能的,这是在 PCL Xamarin 项目中。
private async Task<string> PostFormAsync (string postUrl, string contentType, byte[] formData)
{
try {
HttpWebRequest request = WebRequest.Create (postUrl) as HttpWebRequest;
request.Method = "POST";
request.ContentType = contentType;
request.Headers ["Cookie"] = Constants.Cookie;
byte[] buffer = new byte[4096];
int count = 0;
int length = 0;
using (Stream requestStream = await request.GetRequestStreamAsync ()) {
using (Stream inputStream = new MemoryStream (formData)) {
while ((count = await inputStream.ReadAsync (buffer, 0, buffer.Length)) > 0) {
await requestStream.WriteAsync (buffer, 0, count);
length += count;
Device.BeginInvokeOnMainThread (() => {
_progressBar.Progress = length / formData.Length;
});
}
}
}
_progressBar.Progress = 0;
WebResponse resp = await request.GetResponseAsync ();
using (Stream stream = resp.GetResponseStream ()) {
StreamReader respReader = new StreamReader (stream);
return respReader.ReadToEnd ();
}
} catch (Exception e) {
Debug.WriteLine (e.ToString ());
return String.Empty;
}
}
请注意,我问的是监控一次 upload 4096 字节的进度,而不是 download
我最终通过将 WebRequest 的 AllowWriteStreamBuffering 属性 设置为 false 并将 SendChunked 属性 设置为 true 来完成此操作。
然而 Xamarin.PCL(配置文件 78)不允许您访问 HttpWebRequest 的这些属性,因此我不得不实例化我的 HttpWebRequest 并 return 它来自我平台特定项目中的依赖服务(仅在 iOS 中测试)。
public class WebDependency : IWebDependency
{
public HttpWebRequest GetWebRequest(string uri)
{
var request = WebRequest.Create (uri) as HttpWebRequest;
request.SendChunked = true;
request.AllowWriteStreamBuffering = false;
return request;
}
}
然后实例化我的网络请求 -
HttpWebRequest request = DependencyService.Get<IWebDependency>().GetWebRequest(uri);
我最近编写了一个 C# 函数,它执行多部分表单 post 来上传文件。为了跟踪进度,我将表单数据一次写入 4096 字节的请求流,并在每次写入时回调。但是,似乎在调用 GetResponseAsync() 之前甚至不会发送请求。
如果是这种情况,每写入请求流的 4096 字节的报告是否是上传进度的准确报告?
如果没有,我怎样才能准确报告进度? WebClient 对我来说是不可能的,这是在 PCL Xamarin 项目中。
private async Task<string> PostFormAsync (string postUrl, string contentType, byte[] formData)
{
try {
HttpWebRequest request = WebRequest.Create (postUrl) as HttpWebRequest;
request.Method = "POST";
request.ContentType = contentType;
request.Headers ["Cookie"] = Constants.Cookie;
byte[] buffer = new byte[4096];
int count = 0;
int length = 0;
using (Stream requestStream = await request.GetRequestStreamAsync ()) {
using (Stream inputStream = new MemoryStream (formData)) {
while ((count = await inputStream.ReadAsync (buffer, 0, buffer.Length)) > 0) {
await requestStream.WriteAsync (buffer, 0, count);
length += count;
Device.BeginInvokeOnMainThread (() => {
_progressBar.Progress = length / formData.Length;
});
}
}
}
_progressBar.Progress = 0;
WebResponse resp = await request.GetResponseAsync ();
using (Stream stream = resp.GetResponseStream ()) {
StreamReader respReader = new StreamReader (stream);
return respReader.ReadToEnd ();
}
} catch (Exception e) {
Debug.WriteLine (e.ToString ());
return String.Empty;
}
}
请注意,我问的是监控一次 upload 4096 字节的进度,而不是 download
我最终通过将 WebRequest 的 AllowWriteStreamBuffering 属性 设置为 false 并将 SendChunked 属性 设置为 true 来完成此操作。
然而 Xamarin.PCL(配置文件 78)不允许您访问 HttpWebRequest 的这些属性,因此我不得不实例化我的 HttpWebRequest 并 return 它来自我平台特定项目中的依赖服务(仅在 iOS 中测试)。
public class WebDependency : IWebDependency
{
public HttpWebRequest GetWebRequest(string uri)
{
var request = WebRequest.Create (uri) as HttpWebRequest;
request.SendChunked = true;
request.AllowWriteStreamBuffering = false;
return request;
}
}
然后实例化我的网络请求 -
HttpWebRequest request = DependencyService.Get<IWebDependency>().GetWebRequest(uri);