2012-11-16 26 views
10

tôi cần trợ giúp về hành vi của WebClient.UploadFileAsync() lạ. Tôi đang tải tệp lên Máy chủ HTTP từ xa (nginx) phương thức POST usind. POST được xử lý máng một kịch bản PHP (mà Địa chỉ đề cập đến).WebClient UploadFileMột hành vi lạ trong báo cáo tiến độ

tôi có mã đơn giản này

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); 
    } 
} 

Và trong UploadProgressChanged tôi chỉ cần cập nhật một ProgressBar với ProgressPercentage nhất định. Vấn đề đầu tiên là tỷ lệ phần trăm Progress được báo cáo, với bất kỳ kích thước tập tin là:

[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! 

Vì vậy, tìm kiếm trên web, tôi đã phát hiện ra rằng khi nhảy từ 50-> 100, chỉ là một sự lựa chọn thiết kế trong tỷ lệ phần trăm .. và vì vậy tôi tốt với nó. Vấn đề lạ là ngay cả khi ở mức 50% (khi toàn bộ tệp đã được gửi), giao diện mạng vẫn tạo lưu lượng truy cập và vẫn đang tải lên. Trong thực tế, như bạn có thể thấy từ thời điểm đăng nhập ở trên, phải mất 7 giây, sau khi gửi tệp, để nâng cao thực tế UploadFileCompletedEvent..in, trong khi đó, tôi vẫn gửi tệp qua HTTP.

Vấn đề ở đây là tôi không thể cập nhật giao diện người dùng của mình một cách đáng tin cậy: thanh tiến trình sẽ phát triển đến 50% nhưng sau đó sẽ bị kẹt chờ hoàn tất tải lên (và đây là hành vi xấu kể từ khi có tệp lớn) đáng kể).

Câu hỏi đặt ra là: làm thế nào tôi có thể giữ cho người dùng cập nhật một cách đáng tin cậy về tiến độ tải lên tệp?

Cảm ơn.

P.S. phương thức hoạt động hoàn toàn tốt và tệp được tải lên máy chủ từ xa một cách chính xác. Vấn đề duy nhất là với báo cáo tiến độ.

+0

Nếu mọi thứ đều được gửi thì giải pháp của bạn là câu trả lời và chấp nhận giải pháp đó. –

+0

Đôi khi đăng câu hỏi ở đây cũng giúp bạn tìm ra nó :) –

Trả lời

2

Tôi vừa phát hiện sự cố: nó nằm trong Xác thực HTTP cơ bản. Đối với một số lý do lạ, ngay cả khi tôi chỉ định Credentials, WebClient gửi yêu cầu POST đầu tiên mà không chỉ định thông tin đăng nhập trong Tiêu đề HTTP. Sau khi máy chủ trả lời bằng yêu cầu xác thực, nó sẽ gửi yêu cầu POST thứ hai chỉ định, chính xác, thông tin đăng nhập. Trong 2 lần thử lại đó, ứng dụng của tôi gửi tệp 2 lần! (Đó là lý do tại sao tôi có kinh nghiệm hoạt động tải lên ngay cả sau khi tập tin đã hoàn toàn sai)

Giải pháp là để buộc các xác thực cơ bản HTTP bằng cách thủ công thêm tiêu đề xác thực (và xóa các WebClient.Credentials .. dòng:

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

Cách này yêu cầu POST thứ nhất (và duy nhất), sẽ được gửi chính xác với tiêu đề Xác thực và tiến trình báo cáo chính xác (chỉ để chia sẻ, tôi báo cáo tiến trình trong thanh tiến trình của tôi dưới dạng (e.ProgressPercentage * 2) vì lý do trên

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

Đặt điều này vào đầu yêu cầu đăng bài của bạn với e.ProgressPercentage * 2 cho mục đích báo cáo tiến độ của bạn.