2010-01-19 6 views
8

Nó làm cho tôi bối rối khi tôi đọc bài viết bởi Žarko Gajic hôm nay:Lẫn lộn về vấn đề đồng bộ hóa thread

"Cơ sở dữ liệu Multithreaded Delphi truy vấn"

Điều URL: http://delphi.about.com/od/kbthread/a/query_threading.htm

Sourecode: http://delphi.about.com/library/weekly/code/adothreading.zip

Với mã của thủ tục "TCalcThread.Execute", Tại sao mã sau không cần phải được đặt trong phương thức Synchronize() để ru n?

Line 173: ListBox.Clear; 
Line 179: ListBox.Items.Insert(......); 
Line 188: ListBox.Items.Add('*---------*'); 
Line 195: TicksLabel.Caption := 'Ticks: ' + IntToStr(ticks); 

Các mã này đang vận hành các thành phần VCL và có liên quan đến cập nhật giao diện người dùng. Theo hiểu biết của tôi, các hoạt động này nên được sử dụng đồng bộ hóa luồng và được thực thi bởi luồng chính. Kiến thức của tôi có lỗ hổng không?

Trả lời

18

Đây là trường hợp hiếm hoi mà bạn đang được hưởng lợi thực tế là Windows đang thực hiện đồng bộ hóa luồng cho bạn. Lý do là đối với một hộp danh sách, các mục được xử lý bằng cách sử dụng SendMessage với các thông điệp điều khiển cụ thể. Bởi vì điều này, mỗi cuộc gọi SendMessage đảm bảo rằng thông điệp được xử lý bởi cùng một luồng mà trên đó điều khiển được tạo ra, đặc biệt là luồng chính.

Như tôi đã nói, đây là trường hợp hiếm hoi. Nó cũng gây ra một chuyển đổi luồng cho mỗi trong ba cuộc gọi đó, điều này sẽ làm suy giảm hiệu suất. Bạn vẫn nên sử dụng Synchronize để buộc khối mã đó chạy trong chuỗi chính nơi nó thuộc về. Nó cũng đảm bảo rằng nếu bạn bắt đầu làm việc với một điều khiển không sử dụng nội bộ SendMessage, bạn sẽ không bị cắn.

0

Thật vậy. Có lẽ mẫu không phải là vấn đề gây ra không có thay đổi giao diện người dùng trong khi thread đang thực hiện. Nhưng những thứ giao diện người dùng luôn phải xảy ra bên trong chuỗi giao diện người dùng.

Sự khác biệt duy nhất tôi nhìn thấy giữa sync'ed và các hướng dẫn không sync'ed là:

  • không sync'ed là phương pháp không cấm params nên chương trình sẽ được dificult hơn để viết:)
  • phương pháp sync'ed được cập nhật một TLabel mà không phải là một TControl (nếu tôi nhớ ngày Delphi của tôi) nên nó sử dụng vải trực tiếp ...

Nhưng dù sao: giao diện người dùng được chạm bởi một sợi đơn . Luôn luôn. Một khi tôi muốn cập nhật một TTreeBox bên trong một chủ đề (không có paralelism cũng không cập nhật chéo, chỉ đơn giản là một sợi riêng biệt) và nó là một điều rất xấu (ngẫu nhiên ...)