2009-07-12 44 views

Trả lời

17

Application.DoEvents thường được sử dụng để đảm bảo rằng các sự kiện được xử lý định kỳ khi bạn thực hiện một số thao tác chạy dài trên chuỗi giao diện người dùng.

Giải pháp tốt hơn không phải là để làm điều đó. Thực hiện các hoạt động dài hạn trên các luồng riêng biệt, marshalling đến chuỗi giao diện người dùng (hoặc sử dụng Control.BeginInvoke/Invoke hoặc với BackgroundWorker) khi bạn cần cập nhật giao diện người dùng.

Application.DoEvents giới thiệu khả năng truy cập lại, điều này có thể dẫn đến lỗi rất khó hiểu.

+0

Jon, bạn nói rằng để đảm bảo sự kiện được xử lý định kỳ ... sự kiện nào? trong lập trình tuần tự, giả sử chúng ta có một nút trên biểu mẫu. khi người dùng nhấp vào, ví dụ: độ mờ của biểu mẫu thay đổi ... hiện tại, loại sự kiện nào ở đây ngoại trừ nhấp chuột của nút? – odiseh

+0

Lặp lại, thay đổi kích thước, di chuyển chuột vv Có rất nhiều sự kiện khủng khiếp, ngay cả khi mã ứng dụng của bạn không xử lý rõ ràng hầu hết các sự kiện. –

+0

@JonSkeet Tôi rất thích ý kiến ​​phản hồi của bạn về việc sử dụng hợp lệ các 'DoEvents'. https://stackoverflow.com/questions/45023826/is-this-a-valid-use-of-doevents-sample-project-included –

1

Imho bạn nên ít hơn bao giờ sử dụng nó, vì bạn có thể kết thúc với hành vi rất bất ngờ. Mã vừa tạo là ok. Những thứ như bạn đang thực hiện lại trình xử lý sự kiện mà bạn hiện đang sử dụng, bởi vì người dùng đã nhấn một phím hai lần, v.v. Nếu bạn muốn làm mới một điều khiển để hiển thị quá trình hiện tại bạn nên gọi một cách rõ ràng .Cập nhật trên điều khiển đó thay vì gọi Application.DoEvents.

2

Windows duy trì hàng đợi để tổ chức các sự kiện khác nhau như nhấp, thay đổi kích thước, đóng, v.v. Trong khi điều khiển phản hồi sự kiện, tất cả các sự kiện khác được giữ lại trong hàng đợi. Vì vậy, nếu ứng dụng của bạn mất quá nhiều thời gian để xử lý một lần nhấp nút, phần còn lại của ứng dụng sẽ xuất hiện để đóng băng. Do đó, có thể ứng dụng của bạn xuất hiện không phản hồi trong khi ứng dụng đang xử lý nặng để phản hồi sự kiện. Mặc dù lý tưởng bạn nên xử lý nặng theo cách không đồng bộ để đảm bảo rằng giao diện người dùng không bị đóng băng, giải pháp nhanh chóng và dễ dàng là chỉ cần gọi Application.DoEvents() định kỳ để cho phép các sự kiện đang chờ xử lý được gửi đến ứng dụng của bạn.

Đối với ứng dụng cửa sổ tốt, người dùng cuối không thích khi bất kỳ hình thức ứng dụng nào bị đóng băng trong khi thực hiện thao tác lớn hơn/nặng. Người dùng luôn muốn ứng dụng chạy trơn tru và theo cách phản hồi hơn là đóng băng giao diện người dùng. Nhưng sau khi googling tôi thấy rằng Application.DoEvents() không phải là một thực hành tốt để sử dụng trong ứng dụng thường xuyên hơn, thay vào đó sự kiện này tốt hơn để sử dụng BackGround Worker Thread để thực hiện nhiệm vụ chạy dài mà không có cửa sổ đóng băng.

Bạn có thể có ý tưởng tốt hơn nếu bạn thực tế tìm kiếm nó. Chỉ cần sao chép mã sau và kiểm tra ứng dụng có và không có Application.DoEvents().

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 
     For i As Integer = 0 To 1000 
      System.Threading.Thread.Sleep(100) 
      ListBox1.Items.Add(i.ToString()) 
      Application.DoEvents() 
     Next 
    End Sub 
Các vấn đề liên quan