我一直在尝试跟踪文件上传的进度,但总是陷入死胡同(从C#应用程序上传而不是网页)。
我尝试使用
文件已上传并打印出进度,但进度比实际上传速度快得多,当上传大文件时,进度将在几秒钟内达到最大值,但实际上传需要几分钟(它不仅是等待响应,所有数据尚未到达服务器)。
因此,我尝试使用
请求在整个文件被写入流并且在开始时已经显示完整进度之后才开始(我使用fiddler进行验证)。我还尝试将
我尝试使用
WebClient
,如下所示:class Program
{
static volatile bool busy = true;
static void Main(string[] args)
{
WebClient client = new WebClient();
// Add some custom header information
client.Credentials = new NetworkCredential("username", "password");
client.UploadProgressChanged += client_UploadProgressChanged;
client.UploadFileCompleted += client_UploadFileCompleted;
client.UploadFileAsync(new Uri("http://uploaduri/"), "filename");
while (busy)
{
Thread.Sleep(100);
}
Console.WriteLine("Done: press enter to exit");
Console.ReadLine();
}
static void client_UploadFileCompleted(object sender, UploadFileCompletedEventArgs e)
{
busy = false;
}
static void client_UploadProgressChanged(object sender, UploadProgressChangedEventArgs e)
{
Console.WriteLine("Completed {0} of {1} bytes", e.BytesSent, e.TotalBytesToSend);
}
}
文件已上传并打印出进度,但进度比实际上传速度快得多,当上传大文件时,进度将在几秒钟内达到最大值,但实际上传需要几分钟(它不仅是等待响应,所有数据尚未到达服务器)。
因此,我尝试使用
HttpWebRequest
来流式传输数据(我知道这不是文件上传的确切等效物,因为它不会产生multipart/form-data
内容,但它确实可以说明我的问题)。 我将AllowWriteStreamBuffering = false
设置为建议的ContentLength
,如this question/answer所建议:class Program
{
static void Main(string[] args)
{
FileInfo fileInfo = new FileInfo(args[0]);
HttpWebRequest client = (HttpWebRequest)WebRequest.Create(new Uri("http://uploadUri/"));
// Add some custom header info
client.Credentials = new NetworkCredential("username", "password");
client.AllowWriteStreamBuffering = false;
client.ContentLength = fileInfo.Length;
client.Method = "POST";
long fileSize = fileInfo.Length;
using (FileStream stream = fileInfo.OpenRead())
{
using (Stream uploadStream = client.GetRequestStream())
{
long totalWritten = 0;
byte[] buffer = new byte[3000];
int bytesRead = 0;
while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
{
uploadStream.Write(buffer, 0, bytesRead);
uploadStream.Flush();
Console.WriteLine("{0} of {1} written", totalWritten += bytesRead, fileSize);
}
}
}
Console.WriteLine("Done: press enter to exit");
Console.ReadLine();
}
}
请求在整个文件被写入流并且在开始时已经显示完整进度之后才开始(我使用fiddler进行验证)。我还尝试将
SendChunked
设置为true(同时设置和不设置ContentLength
)。似乎数据仍然会在发送到网络之前被缓存。这些方法中是否有哪一个存在问题,或者也许还有其他方法可以跟踪来自Windows应用程序的文件上传进度?
AllowReadStreamBuffering = false
,这样请求就不会在所有数据“缓存”到本地之前开始。 - Cornelius