我一直在尝试跟踪文件上传的进度,但一直处于死胡同(从 C# 应用程序而不是网页上传)。
我尝试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
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();
}
}
直到整个文件被写入流并且在它开始时已经显示了完整的进度(我正在使用提琴手来验证这一点),该请求才会开始。我也尝试设置SendChunked
为 true (有和没有设置ContentLength
)。似乎数据在通过网络发送之前仍会被缓存。
这些方法中的一种是否有问题,或者是否有另一种方法可以跟踪从 Windows 应用程序上传文件的进度?