2010-08-04 47 views
5

Tôi đang cố gắng sử dụng một nhân viên nền để lấy một lượng lớn dữ liệu từ cơ sở dữ liệu mà không bị trì hoãn chủ đề chính. Điều này có vẻ hoạt động tốt, ngoại trừ khi cập nhật giao diện người dùng, bản cập nhật sẽ đóng băng màn hình. Mã có liên quan như sau:C# Cập nhật giao diện người dùng nền công nhân

private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    {    
     lvwTest.BeginUpdate(); 
     lvwTest.Items.Clear(); 

     // Populate the UI 
     foreach (TestItem ti in testData) 
     { 
      ListViewItem lvi = lvwTest.Items.Add(ti.Value1); 
      lvi.SubItems.Add(ti.Value2); 
     } 

     lvwTest.EndUpdate();      
    } 

Bản cập nhật mất khoảng 2 - 3 giây, khi màn hình bị khóa. Tôi nhận ra rằng chỉ có chủ đề chính mới có thể cập nhật màn hình, nhưng có thể tải dữ liệu này vào bộ nhớ theo một cách nào đó (trong một chuỗi nền hoặc một ví dụ khác của một listview hoặc một cái gì đó) và sau đó chỉ cần hiển thị nó? Tất cả những gì tôi muốn xảy ra là chương trình chỉ cần làm mới dữ liệu mà không cần tốn thời gian trong chuỗi chính.

Trả lời

1

Tôi khuyên bạn nên tải dữ liệu vào bộ nhớ và sử dụng chế độ ảo ListView. Bằng cách đó, bạn chỉ tạo các đối tượng ListViewItem khi cần.

1

Nếu bạn phải tải lượng dữ liệu thực sự khổng lồ vào giao diện người dùng, nó sẽ yêu cầu thời gian và nó sẽ chặn ứng dụng của chúng tôi. Tùy chọn là di chuyển hoặc phân trang thông minh. Bạn tải tất cả dữ liệu nhưng bạn đặt nó từng mảnh theo yêu cầu của người dùng.

0

Ngoài ảo hóa, tôi khuyên bạn nên chia nhỏ các mục thành các lô, ví dụ: 100 và thêm từng lô trong thông báo của riêng nó. Bằng cách đó, giao diện người dùng có thay đổi để xử lý các thư khác trong khi các lô đang được thêm vào ListView.

Nói cách khác, tất cả trình xử lý RunWorkerCompleted sẽ xếp hàng loạt đầu tiên để thêm vào một thư riêng biệt. Phương thức bổ sung sau đó sẽ thêm các mục và sau đó xếp hàng loạt tiếp theo. Điều này sẽ tiếp tục cho đến khi không còn nhiều mục để thêm. Tại thời điểm đó, bạn sẽ bật lại phần có liên quan của giao diện người dùng của mình (số ListView).

0

Vì hầu hết các điều trên đều là lời khuyên tốt, nhưng không thực sự giải quyết vấn đề trước mắt của bạn, đây là một cách tiếp cận khác: Điều này sẽ cập nhật GUI của bạn và giữ cho nó phản hồi. Giả sử bạn đang ở trong ứng dụng WinForm?

 Application.DoEvents(); 
     this.Refresh(); 

Tuy nhiên, điều này không có nghĩa rằng có lẽ bạn không nên nghe theo những ý tưởng từ trên cao :-)

+0

Nó là một ứng dụng WinForm - nhưng trở lại trong những ngày VB6, DoEvents được tán thành bởi vì nó có thể thay đổi chuỗi sự kiện. Đó không phải là trường hợp trong C#? –

+0

Bạn có thể đúng, nó vẫn là một chút của một hack từ những gì tôi đã nghe. Phụ thuộc vào sự phức tạp của ứng dụng của bạn. Tôi đã viết lại ứng dụng đơn giản cuối cùng của mình cho WPF, đó thực sự là một Framework thực sự tốt đẹp. – Remy

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