10

奇妙な WebClient.UploadFileAsync() の動作について助けが必要です。POST メソッドを使用して、ファイルをリモート HTTP サーバー (nginx) にアップロードしています。POST は、PHP スクリプト (Address が参照するもの) を介して処理されます。

私はこの簡単なコードを持っています

public void uploadFile(string filePath)
{
    webClient = new WebClient();
    webClient.Credentials = new NetworkCredential(Constant.HTTPUsername,Constant.HTTPPassword);
    webClient.Headers.Add("Test", TestKey);
    webClient.UploadProgressChanged += webClient_UploadProgressChanged;
    webClient.UploadFileCompleted += webClient_UploadFileCompleted;

    try
    {
        webClient.UploadFileAsync(new Uri(Address), "POST", filePath);
    }
    catch (Exception error)
    {
        throw new CustomException(error.Message);
    }
}

そして UploadProgressChanged では、指定された ProgressPercentage で progressBar を更新するだけです。最初の問題は、レポートされる進行状況のパーセンテージであり、ファイル サイズは次のとおりです。

[17.38.14] Progress: 0 Bytes Sent: 175 / 269264
[17.38.14] Progress: 1 Bytes Sent: 8367 / 269264
[17.38.14] Progress: 3 Bytes Sent: 16559 / 269264
[17.38.14] Progress: 4 Bytes Sent: 24751 / 269264
[17.38.14] Progress: 6 Bytes Sent: 32943 / 269264
[17.38.14] Progress: 7 Bytes Sent: 41135 / 269264
[17.38.14] Progress: 9 Bytes Sent: 49327 / 269264
[17.38.14] Progress: 10 Bytes Sent: 57519 / 269264
[17.38.14] Progress: 12 Bytes Sent: 65711 / 269264
[17.38.14] Progress: 13 Bytes Sent: 73903 / 269264
[17.38.14] Progress: 15 Bytes Sent: 82095 / 269264
[17.38.14] Progress: 16 Bytes Sent: 90287 / 269264
[17.38.14] Progress: 18 Bytes Sent: 98479 / 269264
[17.38.15] Progress: 19 Bytes Sent: 106671 / 269264
[17.38.15] Progress: 21 Bytes Sent: 114863 / 269264
[17.38.15] Progress: 22 Bytes Sent: 123055 / 269264
[17.38.15] Progress: 24 Bytes Sent: 131247 / 269264
[17.38.15] Progress: 25 Bytes Sent: 139439 / 269264
[17.38.15] Progress: 27 Bytes Sent: 147631 / 269264
[17.38.16] Progress: 28 Bytes Sent: 155823 / 269264
[17.38.16] Progress: 30 Bytes Sent: 164015 / 269264
[17.38.16] Progress: 31 Bytes Sent: 172207 / 269264
[17.38.16] Progress: 33 Bytes Sent: 180399 / 269264
[17.38.16] Progress: 35 Bytes Sent: 188591 / 269264
[17.38.16] Progress: 36 Bytes Sent: 196783 / 269264
[17.38.17] Progress: 38 Bytes Sent: 204975 / 269264
[17.38.17] Progress: 39 Bytes Sent: 213167 / 269264
[17.38.17] Progress: 41 Bytes Sent: 221359 / 269264
[17.38.17] Progress: 42 Bytes Sent: 229551 / 269264
[17.38.17] Progress: 44 Bytes Sent: 237743 / 269264
[17.38.17] Progress: 45 Bytes Sent: 245935 / 269264
[17.38.17] Progress: 47 Bytes Sent: 254127 / 269264
[17.38.18] Progress: 48 Bytes Sent: 262319 / 269264
[17.38.18] Progress: 49 Bytes Sent: 269220 / 269264
[17.38.18] Progress: 50 Bytes Sent: 269264 / 269264
[17.38.25] Progress: -50 Bytes Sent: 269264 / 269264
[17.38.25] Progress: 100 Bytes Sent: 269264 / 269264
[17.38.25] FileCompleted event raised!

それで、ウェブで検索すると、50から100へのジャンプは、パーセンテージレポートの設計上の選択にすぎないことがわかりました..そして、私はそれで問題ありません. 奇妙な問題は、50% (ファイル全体が送信されたとき) であっても、ネットワーク インターフェイスがトラフィックを生成し、アップロードを続けていることです。実際、上記のログの時間からわかるように、ファイルが送信されてから UploadFileCompletedEvent が発生するまでに 7 秒かかります。実際、その間、私はまだ HTTP 経由でファイルを送信しています。

ここでの問題は、UI を確実に更新できないことです。プログレス バーは 50% まで伸びますが、アップロードの完了を待ってスタックします (大きなファイルでは時間が大幅に長くなるため、これは悪い動作です)。

問題は、ファイルのアップロードの進行状況をユーザーに確実に最新の状態に保つにはどうすればよいかということです。

ありがとう。

PS メソッドは完全に正常に機能し、ファイルはリモート サーバーに正しくアップロードされます。唯一の問題は、進捗レポートにあります。

4

2 に答える 2

2

私はちょうど問題を見つけました: それは基本的な HTTP 認証にあります。奇妙な理由で、資格情報を指定しても、WebClient は HTTP ヘッダーで資格情報を指定せずに最初の POST 要求を送信します。サーバーは auth-request で応答した後、資格情報を正しく指定して 2 番目の POST 要求を送信します。この 2 回の再試行で、アプリケーションはファイルを 2 回送信します。(そのため、ファイルが完全に送信された後でもアップロード アクティビティが発生しました)

解決策は、Authentication ヘッダーを手動で追加して (および WebClient.Credentials.. 行を削除して)、HTTP 基本認証を強制することです。

string authInfo = userName + ":" + userPassword;
authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
req.Headers["Authorization"] = "Basic " + authInfo;

このようにして、最初の (そして唯一の) POST リクエストが認証ヘッダーと共に正しく送信され、レポートの進行状況が正しくなります (共有するためだけに、上記の理由により、プログレスバーの進行状況を (e.ProgressPercentage * 2) として報告します。

于 2013-09-20T10:25:30.007 に答える
1
string authInfo = userName + ":" + userPassword;
authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
req.Headers["Authorization"] = "Basic " + authInfo;

e.ProgressPercentage * 2進行状況を報告する目的で、投稿リクエストの最初にこれを配置します。

于 2013-03-19T22:54:28.170 に答える