ファイルのアップロードの進行状況を追跡しようとしましたが、行き止まりに陥り続けています (Web ページではなく 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 アプリケーションからのファイルのアップロードの進行状況を追跡できる別の方法がありますか?