2012-10-25 24 views
5

Tôi có một biểu mẫu đơn giản với 2 thanh tiến trình và 1 backgroundworker trên đó. Tôi có 2 vòng lặp (một cái khác) và tôi muốn báo cáo lại tiến trình của mỗi vòng lặp một lần tăng lên. Đây là mã tôi có:Chỉ 1 trong 2 thanh tiến trình được cập nhật trong BackgroundWorker

private void buttonStart_Click(object sender, EventArgs e) 
{ 
    workerCustomers.RunWorkerAsync(); 
} 

private void workerCustomers_ProgressChanged(object sender, ProgressChangedEventArgs e) 
{ 
    progressBar1.Value = e.ProgressPercentage; 
    progressBar2.Value = (int)e.UserState; 
} 

private void workerCustomers_DoWork(object sender, DoWorkEventArgs e) 
{ 
    for (int customer = 0; customer < 50; customer++) 
    { 
     int customerPercentage = ++customer * 100/50; 
     workerCustomers.ReportProgress(customerPercentage, 0); 

     for (int location = 0; location < 500; location++) 
     { 
      int locationPercentage = ++location * 100/500; 
      workerCustomers.ReportProgress(customerPercentage, locationPercentage); 
     } 

     workerCustomers.ReportProgress(customerPercentage, 0); 
    } 
} 

Khi chương trình chạy, progressbar1 được cập nhật tốt, nhưng progressbar2 không bao giờ di chuyển. Nếu tôi chạy nó thông qua trình gỡ lỗi, tôi có thể thấy giá trị của progressbar2 đang được thay đổi, không có thay đổi đồ họa. Bất kỳ ý tưởng?

+0

Giá trị tối đa của thanh tiến trình có được đặt đúng không? –

+0

@lc., Vâng, theo mặc định, nó được đặt thành 100 nhưng tôi đã thay đổi để khớp với tổng số vòng lặp 2 là 500. – Robert

+1

Vòng lặp 500 sẽ hoạt động rất nhanh. Nó có thể không xuất hiện để được cập nhật. Hãy thử thêm một Thread.Sleep() vào vòng lặp bên trong và xem nếu nó thực sự chỉ xảy ra quá nhanh để bạn có thể nhìn thấy. –

Trả lời

5

Có, thanh tiến trình thứ 2 sẽ không cập nhật được nếu bạn đã bật Aero trên màn hình của mình. Trong đó cung cấp thanh tiến trình hoạt hình, thanh màu xanh lá cây theo mặc định với ghi chú đánh dấu di chuyển.

Kiểu thanh tiến trình này đặc biệt, nó nội suy các giá trị trung gian và luôn trơn tru, ngay cả khi bạn chỉ định giá trị khóa học cho thuộc tính Giá trị. Nói cách khác, bạn có thể gán 10, 20, 30, etcetera nhưng thanh không nhảy. Nó trơn tru làm tăng chiều dài thanh.

Điều này có tác dụng phụ. Để làm cho hoạt ảnh này hoạt động, thanh tiến trình phải tụt hậu. Nói cách khác, nó luôn hiển thị giá trị là đằng sau giá trị được lập trình. Và một thời gian phải vượt qua để nó có thể tăng chiều dài thanh một cách trơn tru lên giá trị được lập trình.

Một chi tiết khác bạn cần biết: hoạt ảnh này không không xảy ra khi bạn giảm giá trị thuộc tính Giá trị, ngay lập tức nhảy độ dài thanh.

Vì vậy, vấn đề là bạn đang cập nhật thuộc tính Giá trị ở tốc độ rất cao, nhanh hơn nhiều so với thanh có thể nội suy. Nó không bao giờ có thể bắt kịp. Ngoại trừ khi bạn khởi động lại ở 0, tức thì nhảy thanh. Tỷ lệ này cao đến nỗi các hình ảnh động không bao giờ có thể làm cho nó để 1.

Bạn có thể thấy điều này bằng cách chèn tuyên bố này bên trong vòng lặp bên trong:

System.Threading.Thread.Sleep(1); 

Chơi với giá trị lý luận, bạn có thể cần phải tăng nó đến 16 để thấy bất kỳ sự khác biệt nào. Bạn càng làm cho nó càng cao, thanh tiếp tục làm cho nó bằng nội suy.

Đây tất nhiên không phải là vấn đề thực sự, điều này xảy ra vì nhân viên của bạn không làm bất kỳ công việc thực tế nào. Ngay sau khi bạn bắt đầu viết mã thực BGW này là nghĩa vụ phải làm sau đó bạn cũng sẽ làm giảm tốc độ mà bạn gọi ProgressChanged.

+0

cảm ơn bạn đã trả lời chi tiết này, tôi đã học được rất nhiều. Cách tiếp cận tốt nhất cho vấn đề này là gì? – Robert

+1

Tôi đã rõ ràng về điều đó, đoạn cuối. –

1

Vấn đề nằm trong thực tế là vòng lặp bên trong của bạn quá chặt chẽ đến mức cập nhật gui đăng quá thường xuyên để gui trả lời chính xác. Giải pháp là thêm công việc thực sự của bạn vào vòng lặp bên trong, vì vậy phải mất nhiều thời gian hơn hoặc nếu bạn muốn mô phỏng GUI, bạn chỉ có thể thêm Thread.Sleep(100) để mô phỏng công việc mất một thời gian.

Cũng đảm bảo rằng các thanh tiến trình tối đa của bạn được đặt thành 100, vì đó là giá trị tối đa bạn trả lại cho mỗi.

0

Vấn đề chính của bạn xuất phát từ vòng lặp nội bộ quá nhanh có nghĩa là bạn không thể thực sự thấy tiến độ vì các bản cập nhật quá nhanh để thanh tiến trình xử lý.

dòng của bạn mã:

location * 100/500 

sẽ tương đương với 100 khi bạn hoàn thành các vòng trong, vì vậy có giá trị progressbar max thiết lập để 500 không quan hệ tốt với con số đó. Điều đó có nghĩa là thanh tiến trình của bạn sẽ không bao giờ đạt đến giá trị tối đa.

Các vấn đề liên quan