Я пытался отслеживать ход загрузки файла, но продолжаю зацикливаться (загрузка из приложения 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();
}
}
Запрос не запускается до тех пор, пока весь файл не будет записан в поток, и уже показывает полный прогресс на момент его запуска (я использую fiddler для проверки этого). Я также попытался установить SendChunked
в true (с настройкой ContentLength
и без нее). Кажется, что данные все еще кэшируются перед отправкой по сети.
Что-то не так с одним из этих подходов или, может быть, есть другой способ, которым я могу отслеживать ход загрузки файлов из приложения Windows?